From 7256bb6a169d14f324304509544d9a8ff884ab71 Mon Sep 17 00:00:00 2001 From: galimba Date: Mon, 22 Jul 2024 15:38:44 +0200 Subject: [PATCH 01/79] Update ERC-7208: fix to ODC interface Merged by EIP-Bot. --- ERCS/erc-7208.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/ERCS/erc-7208.md b/ERCS/erc-7208.md index c5cc463ca6..3dd6fca0d5 100644 --- a/ERCS/erc-7208.md +++ b/ERCS/erc-7208.md @@ -87,23 +87,6 @@ interface IODC { */ function allowDataManager(DataPoint dp, address dm, bool approved) external; - /** - * @notice Verifies if DataObject is allowed to add Hooks to the DataPoint - * @param dp Identifier of the DataPoint - * @param dobj Address of DataObject - * @return if write access is allowed - */ - function isApprovedDataObject(DataPoint dp, address dobj) external view returns(bool); - - /** - * @notice Defines if DataObject is allowed to add Hooks to the DataPoint - * @param dp Identifier of the DataPoint - * @param dobj Address of DataObject - * @param approved if DataManager should be approved for the DataPoint - * @dev Function should be restricted to datapoint maintainer only - */ - function allowDataObject(DataPoint dp, address dobj, bool approved) external; - /** * @notice Reads stored data * @param dobj Identifier of DataObject From 84323d0d16c218974b6b76721247862fcde54e02 Mon Sep 17 00:00:00 2001 From: Harpocrates <116655068+harpocrates555@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:20:28 -0400 Subject: [PATCH 02/79] Add ERC: Collateralized NFT Merged by EIP-Bot. --- ERCS/erc-7595.md | 491 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 491 insertions(+) create mode 100644 ERCS/erc-7595.md diff --git a/ERCS/erc-7595.md b/ERCS/erc-7595.md new file mode 100644 index 0000000000..c56748caa4 --- /dev/null +++ b/ERCS/erc-7595.md @@ -0,0 +1,491 @@ +--- +eip: 7595 +title: Collateralized NFT +description: ERC-721 Extension to enable collateralization with ERC-20 based tokens. +author: 571nKY (@571nKY), Cosmos (@Cosmos4k), f4t50 (@f4t50), Harpocrates (@harpocrates555) +discussions-to: https://ethereum-magicians.org/t/collateralized-nft-standard/18097 +status: Draft +type: Standards Track +category: ERC +created: 2023-03-13 +requires: 20, 721 +--- + +## Abstract + +This proposal recommends an extension of [ERC-721](./eip-721.md) to allow for collateralization using a list of [ERC-20](./eip-20.md) based tokens. The proprietor of this ERC collection could hold both the native coin and [ERC-20](./eip-20.md) based tokens, with the `ownerOf` tokenId being able to unlock the associated portion of the underlying [ERC-20](./eip-20.md) balance. + +## Motivation + +The emerging trend of NFT finance focuses on the NFT floor price to enable the market value of the NFT serve as a collateral in lending protocols. The NFT floor price is susceptible to the supply-demand dynamics of the NFT market, characterized by higher volatility compared to the broader crypto market. Furthermore, potential price manipulation in specific NFT collections can artificially inflate NFT market prices, impacting the floor price considered by lending protocols. Relying solely on the NFT floor price based on market value is both unpredictable and unreliable. + +This ERC addresses various challenges encountered by the crypto community with [ERC-721](./eip-721.md) based collections and assets. This ERC brings forth advantages such as sustainable NFT royalties supported by tangible assets, an on-chain verifiable floor price, and the introduction of additional monetization avenues for NFT collection creators. + +### Presets + +* The Basic Preset allows for the evaluation of an on-chain verifiable price floor for a specified NFT asset. + +* The Dynamic Preset facilitates on-chain modification of tokenURI based on predefined collateral rules for a specified NFT asset. + +* With the Royalty Preset, NFT collection creators can receive royalty payments for each transaction involving asset owners and Externally Owned Accounts (EOA), as well as transactions with smart contracts. + +* The VRF Preset enables the distribution of collateral among multiple NFT asset holders using the Verifiable Random Function (VRF) by Chainlink. + +### Extension to Existing ERC-721 Based Collections + +For numerous [ERC-721](./eip-721.md) based collections that cannot be redeployed, we propose the implementation of an abstraction layer embodied by a smart contract. This smart contract would replicate all the functionalities of this ERC standard and grant access to collateral through mapping. + +## Specification +### ERC standard for new NFT collections + +```solidity + +interface IERC721Envious is IERC721 { + event Collateralized(uint256 indexed tokenId, uint256 amount, address tokenAddress); + event Uncollateralized(uint256 indexed tokenId, uint256 amount, address tokenAddress); + event Dispersed(address indexed tokenAddress, uint256 amount); + event Harvested(address indexed tokenAddress, uint256 amount, uint256 scaledAmount); + + /** + * @dev An array with two elements. Each of them represents percentage from collateral + * to be taken as a commission. First element represents collateralization commission. + * Second element represents uncollateralization commission. There should be 3 + * decimal buffer for each of them, e.g. 1000 = 1%. + * + * @param uint 256 index of value in array. + */ + function commissions(uint256 index) external view returns (uint256); + + /** + * @dev 'Black hole' is any address that guarantees that tokens sent to it will not be + * retrieved from it. Note: some tokens revert on transfer to zero address. + * + * @return address address of black hole. + */ + function blackHole() external view returns (address); + + /** + * @dev Token that will be used to harvest collected commissions. + * + * @return address address of token. + */ + function communityToken() external view returns (address); + + /** + * @dev Pool of available tokens for harvesting. + * + * @param uint256 index in array. + * @return address address of token. + */ + function communityPool(uint256 index) external view returns (address); + + /** + * @dev Token balance available for harvesting. + * + * @param address address of token. + * @return uint256 token balance. + */ + function communityBalance(address tokenAddress) external view returns (uint256); + + /** + * @dev Array of tokens that have been dispersed. + * + * @param uint256 index in array. + * @return address address of dispersed token. + */ + function disperseTokens(uint256 index) external view returns (address); + + /** + * @dev Amount of tokens that has been dispersed. + * + * @param address address of token. + * @return uint256 token balance. + */ + function disperseBalance(address tokenAddress) external view returns (uint256); + + /** + * @dev Amount of tokens that was already taken from the disperse. + * + * @param address address of token. + * @return uint256 total amount of tokens already taken. + */ + function disperseTotalTaken(address tokenAddress) external view returns (uint256); + + /** + * @dev Amount of disperse already taken by each tokenId. + * + * @param tokenId unique identifier of unit. + * @param address address of token. + * @return uint256 amount of tokens already taken. + */ + function disperseTaken(uint256 tokenId, address tokenAddress) external view returns (uint256); + + /** + * @dev Mapping of `tokenId`s to token addresses that have collateralized before. + * + * @param tokenId unique identifier of unit. + * @param index in array. + * @return address address of token. + */ + function collateralTokens(uint256 tokenId, uint256 index) external view returns (address); + + /** + * @dev Token balances that are stored under `tokenId`. + * + * @param tokenId unique identifier of unit. + * @param address address of token. + * @return uint256 token balance. + */ + function collateralBalances(uint256 tokenId, address tokenAddress) external view returns (uint256); + + /** + * @dev Calculator function for harvesting. + * + * @param amount of `communityToken`s to spend + * @param address address of token to be harvested + * @return amount to harvest based on inputs + */ + function getAmount(uint256 amount, address tokenAddress) external view returns (uint256); + + /** + * @dev Collect commission fees gathered in exchange for `communityToken`. + * + * @param amounts[] array of amounts to collateralize + * @param address[] array of token addresses + */ + function harvest(uint256[] memory amounts, address[] memory tokenAddresses) external; + + /** + * @dev Collateralize NFT with different tokens and amounts. + * + * @param tokenId unique identifier for specific NFT + * @param amounts[] array of amounts to collateralize + * @param address[] array of token addresses + */ + function collateralize( + uint256 tokenId, + uint256[] memory amounts, + address[] memory tokenAddresses + ) external payable; + + /** + * @dev Withdraw underlying collateral. + * + * Requirements: + * - only owner of NFT + * + * @param tokenId unique identifier for specific NFT + * @param amounts[] array of amounts to collateralize + * @param address[] array of token addresses + */ + function uncollateralize( + uint256 tokenId, + uint256[] memory amounts, + address[] memory tokenAddresses + ) external; + + /** + * @dev Split collateral among all existent tokens. + * + * @param amounts[] to be dispersed among all NFT owners + * @param address[] address of token to be dispersed + */ + function disperse(uint256[] memory amounts, address[] memory tokenAddresses) external payable; +} +``` + +### Abstraction layer for already deployed NFT collections + +```solidity + +interface IEnviousHouse { + event Collateralized( + address indexed collection, + uint256 indexed tokenId, + uint256 amount, + address tokenAddress + ); + + event Uncollateralized( + address indexed collection, + uint256 indexed tokenId, + uint256 amount, + address tokenAddress + ); + + event Dispersed( + address indexed collection, + address indexed tokenAddress, + uint256 amount + ); + + event Harvested( + address indexed collection, + address indexed tokenAddress, + uint256 amount, + uint256 scaledAmount + ); + + /** + * @dev totalCollections function returns the total count of registered collections. + * + * @return uint256 number of registered collections. + */ + function totalCollections() external view returns (uint256); + + /** + * @dev 'Black hole' is any address that guarantees that tokens sent to it will not be + * retrieved from it. Note: some tokens revert on transfer to zero address. + * + * @param address collection address. + * @return address address of black hole. + */ + function blackHole(address collection) external view returns (address); + + /** + * @dev collections function returns the collection address based on the collection index input. + * + * @param uint256 index of a registered collection. + * @return address address collection. + */ + function collections(uint256 index) external view returns (address); + + /** + * @dev collectionIds function returns the collection index based on the collection address input. + * + * @param address collection address. + * @return uint256 collection index. + */ + function collectionIds(address collection) external view returns (uint256); + + /** + * @dev specificCollections function returns whether a particular collection follows the ERC721 standard or not. + * + * @param address collection address. + * @return bool specific collection or not. + */ + function specificCollections(address collection) external view returns (bool); + + /** + * @dev An array with two elements. Each of them represents percentage from collateral + * to be taken as a commission. First element represents collateralization commission. + * Second element represents uncollateralization commission. There should be 3 + * decimal buffer for each of them, e.g. 1000 = 1%. + * + * @param address collection address. + * @param uint256 index of value in array. + * @return uint256 collected commission. + */ + function commissions(address collection, uint256 index) external view returns (uint256); + + /** + * @dev Token that will be used to harvest collected commissions. + * + * @param address collection address. + * @return address address of token. + */ + function communityToken(address collection) external view returns (address); + + /** + * @dev Pool of available tokens for harvesting. + * + * @param address collection address. + * @param uint256 index in array. + * @return address address of token. + */ + function communityPool(address collection, uint256 index) external view returns (address); + + /** + * @dev Token balance available for harvesting. + * + * @param address collection address. + * @param address address of token. + * @return uint256 token balance. + */ + function communityBalance(address collection, address tokenAddress) external view returns (uint256); + + /** + * @dev Array of tokens that have been dispersed. + * + * @param address collection address. + * @param uint256 index in array. + * @return address address of dispersed token. + */ + function disperseTokens(address collection, uint256 index) external view returns (address); + + /** + * @dev Amount of tokens that has been dispersed. + * + * @param address collection address. + * @param address address of token. + * @return uint256 token balance. + */ + function disperseBalance(address collection, address tokenAddress) external view returns (uint256); + + /** + * @dev Amount of tokens that was already taken from the disperse. + * + * @param address collection address. + * @param address address of token. + * @return uint256 total amount of tokens already taken. + */ + function disperseTotalTaken(address collection, address tokenAddress) external view returns (uint256); + + /** + * @dev Amount of disperse already taken by each tokenId. + * + * @param address collection address. + * @param tokenId unique identifier of unit. + * @param address address of token. + * @return uint256 amount of tokens already taken. + */ + function disperseTaken(address collection, uint256 tokenId, address tokenAddress) external view returns (uint256); + + /** + * @dev Mapping of `tokenId`s to token addresses that have collateralized before. + * + * @param address collection address. + * @param tokenId unique identifier of unit. + * @param index in array. + * @return address address of token. + */ + function collateralTokens(address collection, uint256 tokenId, uint256 index) external view returns (address); + + /** + * @dev Token balances that are stored under `tokenId`. + * + * @param address collection address. + * @param tokenId unique identifier of unit. + * @param address address of token. + * @return uint256 token balance. + */ + function collateralBalances(address collection, uint256 tokenId, address tokenAddress) external view returns (uint256); + + /** + * @dev Calculator function for harvesting. + * + * @param address collection address. + * @param amount of `communityToken`s to spend. + * @param address address of token to be harvested. + * @return amount to harvest based on inputs. + */ + function getAmount(address collection, uint256 amount, address tokenAddress) external view returns (uint256); + + /** + * @dev setSpecificCollection function enables the addition of any collection that is not compatible with the ERC721 standard to the list of exceptions. + * + * @param address collection address. + */ + function setSpecificCollection(address collection) external; + + /** + * @dev registerCollection function grants Envious functionality to any ERC721-compatible collection and streamlines + * the distribution of an initial minimum disbursement to all NFT holders. + * + * @param address collection address. + * @param address address of `communityToken`. + * @param uint256 collateralization fee, incoming / 1e5 * 100%. + * @param uint256 uncollateralization fee, incoming / 1e5 * 100%. + */ + function registerCollection( + address collection, + address token, + uint256 incoming, + uint256 outcoming + ) external payable; + + /** + * @dev Collect commission fees gathered in exchange for `communityToken`. + * + * @param address collection address. + * @param amounts[] array of amounts to collateralize. + * @param address[] array of token addresses. + */ + function harvest( + address collection, + uint256[] memory amounts, + address[] memory tokenAddresses + ) external; + + /** + * @dev Collateralize NFT with different tokens and amounts. + * + * @param address collection address. + * @param tokenId unique identifier for specific NFT. + * @param amounts[] array of amounts to collateralize. + * @param address[] array of token addresses. + */ + function collateralize( + address collection, + uint256 tokenId, + uint256[] memory amounts, + address[] memory tokenAddresses + ) external payable; + + /** + * @dev Withdraw underlying collateral. + * + * Requirements: + * - only owner of NFT + * + * @param address collection address. + * @param tokenId unique identifier for specific NFT. + * @param amounts[] array of amounts to collateralize. + * @param address[] array of token addresses. + */ + function uncollateralize( + address collection, + uint256 tokenId, + uint256[] memory amounts, + address[] memory tokenAddresses + ) external; + + /** + * @dev Split collateral among all existent tokens. + * + * @param address collection address. + * @param amounts[] to be dispersed among all NFT owners. + * @param address[] address of token to be dispersed. + */ + function disperse( + address collection, + uint256[] memory amounts, + address[] memory tokenAddresses + ) external payable; +} +``` + +## Rationale +### “Envious” Term Choice +We propose adopting the term "Envious" to describe any NFT collection minted using this ERC standard or any [ERC-721](./eip-721.md) based NFT collection that utilized the EnviousHouse abstraction layer. + +### NFT Collateralization with Multiple Tokens +Some Web3 projects primarily collateralize a specific NFT asset with one [ERC-20](./eip-20.md) based token, resulting in increased gas fees and complications in User Experience (UX). + +This ERC has been crafted to enable the collateralization of a designated NFT asset with multiple [ERC-20](./eip-20.md) based tokens within a single transaction. + +### NFT Collateralization with the Native Coin +Each [ERC-20](./eip-20.md) based token possesses a distinct address. However, a native coin does not carry an address. To address this, we propose utilizing a null address (`0x0000000000000000000000000000000000000000`) as an identifier for the native coin during collateralization, as it eliminates the possibility of collisions with smart contract addresses. + +### Disperse Functionality +We have implemented the capability to collateralize all assets within a particular NFT collection in a single transaction. The complete collateral amount is deposited into a smart contract, enabling each user to claim their respective share of the collateral when they add or redeem collateral for that specific asset. + +### Harvest Functionality +Each Envious NFT collection provides an option to incorporate a community [ERC-20](./eip-20.md) based token, which can be exchanged for commissions accrued from collateralization and uncollateralization activities. + +### BlackHole Instance +Some [ERC-20](./eip-20.md) based token implementations forbid transfers to the null address, it is necessary to have a reliable burning mechanism in the harvest transactions. `blackHole` smart contract removes [ERC-20](./eip-20.md) communityTokens from the circulating supply in exchange for commission fees withdrawn. + +`blackHole` has been designed to prevent the transfer of any tokens from itself and can only perform read operations. It is intended to be used with the Envious extension in implementations related to commission harvesting. + +## Backwards Compatibility + +EnviousHouse abstraction layer is suggested for already deployed [ERC-721](./eip-721.md) based NFT collections. + +## Security Considerations + +Envious may share security concerns similar to those found in [ERC-721](./eip-721.md), such as hidden logic within functions like burn, add resource, accept resource, etc. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From a247eddf895286331eab23990fd9905d80dd8d42 Mon Sep 17 00:00:00 2001 From: rickey <12867336+HelloRickey@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:32:51 +0800 Subject: [PATCH 03/79] Update ERC-7654: Add payable for POST and PUT methods Merged by EIP-Bot. --- ERCS/erc-7654.md | 4 ++-- assets/erc-7654/RequestMethodTypes.sol | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ERCS/erc-7654.md b/ERCS/erc-7654.md index edfd53de14..8e2eb4621f 100644 --- a/ERCS/erc-7654.md +++ b/ERCS/erc-7654.md @@ -97,7 +97,7 @@ interface IRequestMethodTypes{ * @param _methodReq is the method type. * @return The response to the post request. */ - function post(string memory _methodName,bytes memory _methodReq)external returns(bytes memory); + function post(string memory _methodName,bytes memory _methodReq)external payable returns(bytes memory); /** * Request the contract to update a record. @@ -105,7 +105,7 @@ interface IRequestMethodTypes{ * @param _methodReq is the method type. * @return The response to the put request. */ - function put(string memory _methodName,bytes memory _methodReq)external returns(bytes memory); + function put(string memory _methodName,bytes memory _methodReq)external payable returns(bytes memory); /** * Supported request method types. diff --git a/assets/erc-7654/RequestMethodTypes.sol b/assets/erc-7654/RequestMethodTypes.sol index b3c3221402..0dd2b9c204 100644 --- a/assets/erc-7654/RequestMethodTypes.sol +++ b/assets/erc-7654/RequestMethodTypes.sol @@ -59,7 +59,7 @@ contract RequestMethodTypes is IRequestMethodTypes{ } } - function post(string memory _methodName,bytes memory _methodReq)public returns(bytes memory){ + function post(string memory _methodName,bytes memory _methodReq)public payable returns(bytes memory){ if(compareStrings(_methodName,"createUser")){ (string memory name,uint256 age)=abi.decode(_methodReq, (string,uint256)); users[msg.sender]=Profiles(name,age); @@ -68,7 +68,7 @@ contract RequestMethodTypes is IRequestMethodTypes{ return abi.encode(""); } - function put(string memory _methodName,bytes memory _methodReq)public returns(bytes memory){ + function put(string memory _methodName,bytes memory _methodReq)public payable returns(bytes memory){ if(compareStrings(_methodName,"updateUserName")){ (address userAddress,string memory name)=abi.decode(_methodReq, (address,string)); require(userAddress==msg.sender); From 695d8dd6bc2806dff70ab066656d9a95602fdb76 Mon Sep 17 00:00:00 2001 From: Jeroen <1748621+hieronx@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:11:47 +0200 Subject: [PATCH 04/79] Add ERC: Authorize Operator (#536) * Move ERC7575 to Last Call * Clarifications * Fix reference implementation, add pipe explanation * Fix typo * Move ERC7540 to Last Call * requester => controller * chore: add author * fix: undo status change * comments * Authorize operator ERC * Update * feat: add motivation and rationale * Add * Update filename * Add discussions link * Add domain separator * Add authorizations lookup * Fix reference implementation * Fix eipw --------- Co-authored-by: Timepunk <45543880+0xTimepunk@users.noreply.github.com> Co-authored-by: Joey Santoro --- ERCS/erc-7741.md | 211 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 ERCS/erc-7741.md diff --git a/ERCS/erc-7741.md b/ERCS/erc-7741.md new file mode 100644 index 0000000000..7c7c6f57d7 --- /dev/null +++ b/ERCS/erc-7741.md @@ -0,0 +1,211 @@ +--- +eip: 7741 +title: Authorize Operator +description: Set Operator via EIP-712 secp256k1 signatures +author: Jeroen Offerijns (@hieronx), João Martins (@0xTimepunk) +discussions-to: https://ethereum-magicians.org/t/erc-7741-authorize-operator/20531 +status: Draft +type: Standards Track +category: ERC +created: 2024-06-03 +requires: 712, 1271 +--- + +## Abstract + +A set of functions to enable meta-transactions and atomic interactions with contracts implementing an operator model, via signatures conforming to the [EIP-712](./eip-712.md) typed message signing specification. + +## Motivation + +The primary motivation for this standard is to enhance the flexibility, security, and efficiency of operator management. By leveraging EIP-712 signatures, this standard allows users to authorize operators without the need for on-chain transactions, reducing gas costs and improving user experience. This is particularly beneficial whenever frequent operator changes and cross-chain interactions are required. + +Additionally, this standard aims to: + +1. **Enable Meta-Transactions**: Allow users to delegate the execution of transactions to operators, enabling meta-transactions where the user does not need to hold native tokens to pay for gas fees on each chain. +2. **Improve Security**: Utilize the EIP-712 standard for typed data signing, which provides a more secure and user-friendly way to sign messages compared to raw data signing. +3. **Facilitate Interoperability**: Provide a standardized interface for operator management that can be adopted across various vault protocols, promoting interoperability and reducing integration complexity for developers. +4. **Streamline Cross-Chain Operations**: Simplify the process of managing operators across different chains, making it easier for protocols to maintain consistent operator permissions and interactions in a multi-chain environment. + +By addressing these needs, the `Authorize Operator` standard aims to streamline the process of managing operators in decentralized vault protocols, making it easier for users and developers to interact with smart contracts in a secure, cost-effective, and interoperable manner across multiple blockchain networks. + +## Specification + +### Operator-compatible contracts + +This signed authorization scheme applies to any contracts implementing the following interface: + +```solidity + interface IOperator { + event OperatorSet(address indexed owner, address indexed operator, bool approved); + + function setOperator(address operator, bool approved) external returns (bool); + function isOperator(address owner, address operator) external returns (bool status); + } +``` + +[EIP-6909](./eip-6909.md) and [EIP-7540](./eip-7540.md) already implement this interface. + +The naming of the arguments is interchangeable, e.g. [EIP-6909](./eip-6909.md) uses `spender` instead of `operator`. + +### Methods + +#### `authorizeOperator` + +Grants or revokes permissions for `operator` to manage Requests on behalf of the `msg.sender`, using an [EIP-712](./eip-712.md) signature. + +MUST revert if the `deadline` has passed. + +MUST invalidate the nonce of the signature to prevent message replay. + +MUST revert if the `signature` is not a valid [EIP-712](./eip-712.md) signature, with the given input parameters. + +MUST set the operator status to the `approved` value. + +MUST log the `OperatorSet` event. + +MUST return `true`. + +```yaml +- name: authorizeOperator + type: function + stateMutability: nonpayable + + inputs: + - name: owner + type: address + - name: operator + type: address + - name: approved + type: bool + - name: deadline + type: uint256 + - name: nonce + type: bytes32 + - name: signature + type: bytes + + outputs: + - name: success + type: bool +``` + +#### `invalidateNonce` + +Revokes the given `nonce` for `msg.sender` as the `owner`. + +```yaml +- name: invalidateNonce + type: function + stateMutability: nonpayable + + inputs: + - name: nonce + type: bytes32 +``` + +#### `authorizations` + +Returns whether the given `nonce` has been used for the `controller`. + +```yaml +- name: authorizations + type: function + stateMutability: nonpayable + + inputs: + - name: controller + type: address + - name: nonce + type: bytes32 + outputs: + - name: used + type: bool +``` + +#### `DOMAIN_SEPARATOR` + +Returns the `DOMAIN_SEPARATOR` as defined according to EIP-712. The `DOMAIN_SEPARATOR` should be unique to the contract and chain to prevent replay attacks from other domains, and satisfy the requirements of EIP-712, but is otherwise unconstrained. + +```yaml +- name: DOMAIN_SEPARATOR + type: function + stateMutability: nonpayable + + outputs: + - type: bytes32 +``` + +### [ERC-165](./eip-165.md) support + +Smart contracts implementing this standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. + +Contracts MUST return the constant value `true` if `0x7a7911eb` is passed through the `interfaceID` argument. + +## Rationale + +### Similarity to [ERC-2612](./eip-2612.md) + +The specification is intentionally designed to closely match [ERC-2612](./eip-2612.md). This should simplify new integrations of the standard. + +The main difference is using `bytes32` vs `uint256`, which enables unordered nonces. + +## Reference Implementation + +```solidity + // This code snippet is incomplete pseudocode used for example only and is no way intended to be used in production or guaranteed to be secure + + bytes32 public constant AUTHORIZE_OPERATOR_TYPEHASH = + keccak256("AuthorizeOperator(address controller,address operator,bool approved,uint256 deadline,bytes32 nonce)"); + + mapping(address owner => mapping(bytes32 nonce => bool used)) authorizations; + + function DOMAIN_SEPARATOR() public view returns (bytes32) { + // EIP-712 implementation + } + + function isValidSignature(address signer, bytes32 digest, bytes memory signature) internal view returns (bool valid) { + // ERC-1271 implementation + } + + function authorizeOperator( + address controller, + address operator, + bool approved, + uint256 deadline, + bytes32 nonce, + bytes memory signature + ) external returns (bool success) { + require(block.timestamp <= deadline, "ERC7540Vault/expired"); + require(controller != address(0), "ERC7540Vault/invalid-controller"); + require(!authorizations[controller][nonce], "ERC7540Vault/authorization-used"); + + authorizations[controller][nonce] = true; + + bytes32 digest = keccak256( + abi.encodePacked( + "\x19\x01", + DOMAIN_SEPARATOR(), + keccak256(abi.encode(AUTHORIZE_OPERATOR_TYPEHASH, controller, operator, approved, deadline, nonce)) + ) + ); + + require(SignatureLib.isValidSignature(controller, digest, signature), "ERC7540Vault/invalid-authorization"); + + isOperator[controller][operator] = approved; + emit OperatorSet(controller, operator, approved); + + success = true; + } + + function invalidateNonce(bytes32 nonce) external { + authorizations[msg.sender][nonce] = true; + } +``` + +## Security Considerations + +Operators have significant control over users and the signed message can lead to undesired outcomes. The expiration date should be set as short as feasible to reduce the chance of an unused signature leaking at a later point. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From fbdc10f87ebe572f7129b6263430d59910d7edf6 Mon Sep 17 00:00:00 2001 From: ligi Date: Tue, 23 Jul 2024 16:44:49 +0200 Subject: [PATCH 05/79] Update ERC-3770: Move to Draft Merged by EIP-Bot. --- ERCS/erc-3770.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-3770.md b/ERCS/erc-3770.md index 41334680d0..fbed54b7c5 100644 --- a/ERCS/erc-3770.md +++ b/ERCS/erc-3770.md @@ -4,7 +4,7 @@ title: Chain-specific addresses description: Prepending chain-specific addresses with a human-readable chain identifier author: Lukas Schor (@lukasschor), Richard Meissner (@rmeissner), Pedro Gomes (@pedrouid), ligi discussions-to: https://ethereum-magicians.org/t/chain-specific-addresses/6449 -status: Stagnant +status: Draft type: Standards Track category: ERC created: 2021-08-26 @@ -58,7 +58,7 @@ Ethereum addresses without the chain specifier will continue to require addition ## Security Considerations -The Ethereum List curators must consider how similar looking chain short names can be used to confuse users. +Similar looking chain short names can be used to confuse users. ## Copyright From 5ab0970a130ff07ce4dacee570a0c5b25eb90c35 Mon Sep 17 00:00:00 2001 From: "J.D. Bertron" Date: Tue, 23 Jul 2024 08:52:42 -0600 Subject: [PATCH 06/79] Update ERC-5630: Move to Draft Merged by EIP-Bot. --- ERCS/erc-5630.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-5630.md b/ERCS/erc-5630.md index 70003c83c2..45cea4e9d3 100644 --- a/ERCS/erc-5630.md +++ b/ERCS/erc-5630.md @@ -4,7 +4,7 @@ title: New approach for encryption / decryption description: defines a specification for encryption and decryption using Ethereum wallets. author: Firn Protocol (@firnprotocol), Fried L. Trout, Weiji Guo (@weijiguo) discussions-to: https://ethereum-magicians.org/t/eip-5630-encryption-and-decryption/10761 -status: Stagnant +status: Draft type: Standards Track category: ERC created: 2022-09-07 From c05baa7d0b1a1961ec7f943a00b8358736ce1e7a Mon Sep 17 00:00:00 2001 From: Peter Kohl-Landgraf <32535675+pekola@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:49:08 +0200 Subject: [PATCH 07/79] Website: Update ERC-6123 - Streamlined Reference Implementation, added Unit Tests Merged by EIP-Bot. --- ERCS/erc-6123.md | 17 +- assets/erc-6123/contracts/ERC20Settlement.sol | 37 +- assets/erc-6123/contracts/ISDC.sol | 61 ++-- assets/erc-6123/contracts/SDC.sol | 168 ++++++---- .../erc-6123/contracts/SDCPledgedBalance.sol | 201 +++++------ assets/erc-6123/doc/sequence.puml | 4 +- assets/erc-6123/package.json | 2 +- assets/erc-6123/test/SDCTests.js | 316 +++++++++++++----- 8 files changed, 500 insertions(+), 306 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index 6625fe55fa..591bd4dcef 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -65,7 +65,7 @@ The following methods specify a Smart Derivative Contract's trade initiation and A party can initiate a trade by providing the party address to trade with, trade data, trade position, payment amount for the trade and initial settlement data. Only registered counterparties are allowed to use that function. ```solidity -function inceptTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external; +function inceptTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; ``` #### Trade Initiation Phase: `confirmTrade` @@ -73,7 +73,7 @@ function inceptTrade(address _withParty, string memory _tradeData, int _position A counterparty can confirm a trade by providing its trade specification data, which then gets matched against the data stored from `inceptTrade` call. ```solidity -function confirmTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external; +function confirmTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; ``` #### Trade Initiation Phase: `cancelTrade` @@ -81,7 +81,7 @@ function confirmTrade(address _withParty, string memory _tradeData, int _positio The counterparty that called `inceptTrade` has the option to cancel the trade, e.g., in the case where the trade is not confirmed in a timely manner. ```solidity -function cancelTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external; +function cancelTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; ``` #### Trade Settlement Phase: `initiateSettlement` @@ -106,18 +106,19 @@ function performSettlement(int256 settlementAmount, string memory settlementData This method - either called back from the provided settlement token directly or from an eligible address - completes the settlement transfer. This might result in a termination or start of the next settlement phase, depending on the provided success flag. +The transactionData is emitted as part of the corresponding event: `TradeSettled` or `TradeTerminated` ```solidity -function afterTransfer(uint256 transactionHash, bool success) external; +function afterTransfer(bool success, uint256 transactionData) external; ``` #### Trade Termination: `requestTermination` -Allows an eligible party to request a mutual termination with a termination amount she is willing to pay and provide further termination terms (e.g. an XML) +Allows an eligible party to request a mutual termination of the trade with the correspondig `tradeData` with a termination amount she is willing to pay and provide further termination terms (e.g. an XML) ```solidity -function requestTradeTermination(string memory tradeId, int256 _terminationPayment, string memory terminationTerms) external; +function requestTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; ``` #### Trade Termination: `confirmTradeTermination` @@ -125,7 +126,7 @@ function requestTradeTermination(string memory tradeId, int256 _terminationPayme Allows an eligible party to confirm a previously requested (mutual) trade termination, including termination payment value and termination terms ```solidity -function confirmTradeTermination(string memory tradeId, int256 _terminationPayment, string memory terminationTerms) external; +function confirmTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; ``` #### Trade Termination: `cancelTradeTermination` @@ -133,7 +134,7 @@ function confirmTradeTermination(string memory tradeId, int256 _terminationPayme The party that initiated `requestTradeTermination` has the option to withdraw the request, e.g., in the case where the termination is not confirmed in a timely manner. ```solidity -function cancelTradeTermination(string memory tradeId, int256 _terminationPayment, string memory terminationTerms) external; +function cancelTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; ``` ### Trade Events diff --git a/assets/erc-6123/contracts/ERC20Settlement.sol b/assets/erc-6123/contracts/ERC20Settlement.sol index c6fedc9e5f..5aedb06d25 100644 --- a/assets/erc-6123/contracts/ERC20Settlement.sol +++ b/assets/erc-6123/contracts/ERC20Settlement.sol @@ -38,25 +38,14 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ } function checkedTransfer(address to, uint256 value, uint256 transactionID) public onlySDC{ - try this.transfer(to,value) returns (bool transferSuccessFlag) { - ISDC(sdcAddress).afterTransfer(transactionID, transferSuccessFlag); - } - catch{ - ISDC(sdcAddress).afterTransfer(transactionID, false); - } + if ( balanceOf(sdcAddress) < value) + ISDC(sdcAddress).afterTransfer(false, transactionID); + else + ISDC(sdcAddress).afterTransfer(true, transactionID); } - function checkedTransferFrom(address from, address to, uint256 value, uint256 transactionID) external onlySDC { - // TODO: Bug - reason="Error: Transaction reverted: contract call run out of gas and made the transaction revert", method="estimateGas", - if (this.balanceOf(from)< value || this.allowance(from,address(msg.sender)) < value ) - ISDC(sdcAddress).afterTransfer(transactionID, false); - try this.transfer(to,value) returns (bool transferSuccessFlag) { - ISDC(sdcAddress).afterTransfer(transactionID, transferSuccessFlag); - } - catch{ - ISDC(sdcAddress).afterTransfer(transactionID, false); - } - // address owner = _msgSender(); // currently not used + function checkedTransferFrom(address from, address to, uint256 value, uint256 transactionID) external view onlySDC { + revert("not implemented"); } function checkedBatchTransfer(address[] memory to, uint256[] memory values, uint256 transactionID ) public onlySDC{ @@ -65,14 +54,14 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ for(uint256 i = 0; i < values.length; i++) requiredBalance += values[i]; if (balanceOf(msg.sender) < requiredBalance){ - ISDC(sdcAddress).afterTransfer(transactionID, false); + ISDC(sdcAddress).afterTransfer(false, transactionID); return; } else{ for(uint256 i = 0; i < to.length; i++){ - transfer(to[i],values[i]); + _transfer(sdcAddress,to[i],values[i]); } - ISDC(sdcAddress).afterTransfer(transactionID, true); + ISDC(sdcAddress).afterTransfer(true, transactionID); } } @@ -88,15 +77,15 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ totalRequiredBalance += values[j]; } if (balanceOf(fromAddress) < totalRequiredBalance){ - ISDC(sdcAddress).afterTransfer(transactionID, false); - break; + ISDC(sdcAddress).afterTransfer(false, transactionID); + return; } } for(uint256 i = 0; i < to.length; i++){ - transferFrom(from[i],to[i],values[i]); + _transfer(from[i],to[i],values[i]); } - ISDC(sdcAddress).afterTransfer(transactionID, true); + ISDC(sdcAddress).afterTransfer(true, transactionID); } } \ No newline at end of file diff --git a/assets/erc-6123/contracts/ISDC.sol b/assets/erc-6123/contracts/ISDC.sol index 88804d1fc4..e82b4d3a8c 100644 --- a/assets/erc-6123/contracts/ISDC.sol +++ b/assets/erc-6123/contracts/ISDC.sol @@ -93,7 +93,7 @@ interface ISDC { /** * @dev Emitted when an active trade is terminated - * @param cause string holding the cause of the termination + * @param cause string holding data associated with the termination, e.g. transactionData upon a failed transaction */ event TradeTerminated(string cause); @@ -105,7 +105,7 @@ interface ISDC { /** * @dev Emitted when settlement process has been finished */ - event TradeSettled(); + event TradeSettled(string transactionData); /** * @dev Emitted when a settlement gets requested @@ -152,35 +152,35 @@ interface ISDC { /** * @notice Incepts a trade, stores trade data * @dev emits a {TradeIncepted} event - * @param _withParty is the party the inceptor wants to trade with - * @param _tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml - * @param _position is the position the inceptor has in that trade - * @param _paymentAmount is the payment amount which can be positive or negative (viewed from the inceptor) - * @param _initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) + * @param withParty is the party the inceptor wants to trade with + * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param position is the position the inceptor has in that trade + * @param paymentAmount is the payment amount which can be positive or negative (viewed from the inceptor) + * @param initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) */ - function inceptTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external; + function inceptTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; /** * @notice Performs a matching of provided trade data and settlement data of a previous trade inception * @dev emits a {TradeConfirmed} event if trade data match - * @param _withParty is the party the confirmer wants to trade with - * @param _tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml - * @param _position is the position the confirmer has in that trade (negative of the position the inceptor has in the trade) - * @param _paymentAmount is the payment amount which can be positive or negative (viewed from the confirmer, negative of the inceptor's view) - * @param _initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) + * @param withParty is the party the confirmer wants to trade with + * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param position is the position the confirmer has in that trade (negative of the position the inceptor has in the trade) + * @param paymentAmount is the payment amount which can be positive or negative (viewed from the confirmer, negative of the inceptor's view) + * @param initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) */ - function confirmTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external; + function confirmTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; /** * @notice Performs a matching of provided trade data and settlement data of a previous trade inception. Required to be called by inceptor. * @dev emits a {TradeCanceled} event if trade data match and msg.sender agrees with the party that incepted the trade. - * @param _withParty is the party the inceptor wants to trade with - * @param _tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml - * @param _position is the position the inceptor has in that trade - * @param _paymentAmount is the payment amount which can be positive or negative (viewed from the inceptor) - * @param _initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) + * @param withParty is the party the inceptor wants to trade with + * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param position is the position the inceptor has in that trade + * @param paymentAmount is the payment amount which can be positive or negative (viewed from the inceptor) + * @param initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) */ - function cancelTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external; + function cancelTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; /// Settlement Cycle: Settlement @@ -202,9 +202,10 @@ interface ISDC { /** * @notice May get called from outside to to finish a transfer (callback). The trade decides on how to proceed based on success flag * @param success tells the protocol whether transfer was successful + * @param transactionData data associtated with the transfer, will be emitted via the events. * @dev may emit a {TradeSettled} event or a {TradeTerminated} event */ - function afterTransfer(uint256 transactionHash, bool success) external; + function afterTransfer(bool success, uint256 transactionData) external; /// Trade termination @@ -212,25 +213,27 @@ interface ISDC { /** * @notice Called from a counterparty to request a mutual termination * @dev emits a {TradeTerminationRequest} - * @param tradeId the trade identifier which is supposed to be terminated - * @param terminationTerms the termination terms + * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param terminationPayment an agreed termination amount (viewed from the requester) + * @param terminationTerms the termination terms to be stored on chain. */ - function requestTradeTermination(string memory tradeId, int256 _terminationPayment, string memory terminationTerms) external; + function requestTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; /** * @notice Called from a party to confirm an incepted termination, which might trigger a final settlement before trade gets closed * @dev emits a {TradeTerminationConfirmed} - * @param tradeId the trade identifier of the trade which is supposed to be terminated - * @param terminationTerms the termination terms + * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param terminationPayment an agreed termination amount (viewed from the confirmer, negative of the value provided by the requester) + * @param terminationTerms the termination terms to be stored on chain. */ - function confirmTradeTermination(string memory tradeId, int256 _terminationPayment, string memory terminationTerms) external; + function confirmTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; /** * @notice Called from a party to confirm an incepted termination, which might trigger a final settlement before trade gets closed * @dev emits a {TradeTerminationConfirmed} - * @param tradeId the trade identifier of the trade which is supposed to be terminated + * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml * @param terminationTerms the termination terms */ - function cancelTradeTermination(string memory tradeId, int256 _terminationPayment, string memory terminationTerms) external; + function cancelTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; } diff --git a/assets/erc-6123/contracts/SDC.sol b/assets/erc-6123/contracts/SDC.sol index 7d61ef9a41..71c3eba737 100644 --- a/assets/erc-6123/contracts/SDC.sol +++ b/assets/erc-6123/contracts/SDC.sol @@ -41,20 +41,24 @@ abstract contract SDC is ISDC { Confirmed, /* - * Valuation Phase + * Valuation Phase: The contract is awaiting a valuation for the next settlement. */ Valuation, /* - * A Token-based Transfer is in Progress + * Token-based Transfer is in Progress. Contracts awaits termination of token transfer (allows async transfers). */ InTransfer, /* - * Settlement is Completed + * Settlement is Completed. */ Settled, + /* + * Termination is in Progress. + */ + InTermination, /* * Terminated. */ @@ -65,29 +69,32 @@ abstract contract SDC is ISDC { * Modifiers serve as guards whether at a specific process state a specific function can be called */ - modifier onlyWhenTradeInactive() { require(tradeState == TradeState.Inactive, "Trade state is not 'Inactive'."); _; } + modifier onlyWhenTradeIncepted() { require(tradeState == TradeState.Incepted, "Trade state is not 'Incepted'."); _; } + modifier onlyWhenSettled() { require(tradeState == TradeState.Settled, "Trade state is not 'Settled'."); _; } + modifier onlyWhenValuation() { require(tradeState == TradeState.Valuation, "Trade state is not 'Valuation'."); _; } - modifier onlyWhenInTransfer() { - require(tradeState == TradeState.InTransfer, "Trade state is not 'InTransfer'."); _; - } - TradeState internal tradeState; + modifier onlyWhenInTermination () { + require(tradeState == TradeState.InTermination, "Trade state is not 'InTermination'."); _; + } modifier onlyCounterparty() { require(msg.sender == party1 || msg.sender == party2, "You are not a counterparty."); _; } + TradeState private tradeState; + address internal party1; address internal party2; address internal receivingParty; @@ -95,12 +102,8 @@ abstract contract SDC is ISDC { string internal tradeID; string internal tradeData; mapping(uint256 => address) internal pendingRequests; // Stores open request hashes for several requests: initiation, update and termination - bool internal mutuallyTerminated = false; int256 terminationPayment; - - int256[] internal settlementAmounts; - string[] internal settlementData; - + int256 upfrontPayment; /* * SettlementToken holds: @@ -116,12 +119,15 @@ abstract contract SDC is ISDC { address _party2, address _settlementToken ) { + terminationPayment = 0; + upfrontPayment = 0; party1 = _party1; party2 = _party2; settlementToken = ERC20Settlement(_settlementToken); settlementToken.setSDCAddress(address(this)); tradeState = TradeState.Inactive; } + /* * generates a hash from tradeData and generates a map entry in openRequests * emits a TradeIncepted @@ -134,6 +140,7 @@ abstract contract SDC is ISDC { uint256 transactionHash = uint256(keccak256(abi.encode(msg.sender,_withParty,_tradeData,_position, _paymentAmount,_initialSettlementData))); pendingRequests[transactionHash] = msg.sender; receivingParty = _position == 1 ? msg.sender : _withParty; + upfrontPayment = _position == 1 ? _paymentAmount : -_paymentAmount; // upfrontPayment is saved with view on the receiving party tradeID = Strings.toString(transactionHash); tradeData = _tradeData; // Set trade data to enable querying already in inception state emit TradeIncepted(msg.sender, tradeID, _tradeData); @@ -152,18 +159,9 @@ abstract contract SDC is ISDC { delete pendingRequests[transactionHash]; // Delete Pending Request tradeState = TradeState.Confirmed; emit TradeConfirmed(msg.sender, tradeID); - address upfrontPayer; - if (_position==1 && _paymentAmount < 0) // payment amount negative means from a long position : party has to pay - upfrontPayer = msg.sender; - else if (_position==1 && _paymentAmount > 0) - upfrontPayer = _withParty; - else if (_position==-1 && _paymentAmount < 0) // payment amount negative means from a short position : party has to pay - upfrontPayer = msg.sender; - else - upfrontPayer = _withParty; - settlementData.push(_initialSettlementData); - uint256 absPaymentAmount = uint256(abs(_paymentAmount)); - processTradeAfterConfirmation(upfrontPayer, absPaymentAmount); + address upfrontPayer = upfrontPayment > 0 ? otherParty(receivingParty) : receivingParty; + uint256 upfrontTransferAmount = uint256(abs(_paymentAmount)); + processTradeAfterConfirmation(upfrontPayer, upfrontTransferAmount,_initialSettlementData); } /* @@ -191,8 +189,8 @@ abstract contract SDC is ISDC { require(keccak256(abi.encodePacked(tradeID)) == keccak256(abi.encodePacked(_tradeId)), "Trade ID mismatch"); uint256 hash = uint256(keccak256(abi.encode(_tradeId, "terminate", _terminationPayment, terminationTerms))); pendingRequests[hash] = msg.sender; - - emit TradeTerminationRequest(msg.sender, _tradeId, _terminationPayment, terminationTerms); + terminationPayment = _terminationPayment; // termination payment will be provided in view of receiving party + emit TradeTerminationRequest(msg.sender, _tradeId, terminationPayment, terminationTerms); } /* @@ -205,13 +203,13 @@ abstract contract SDC is ISDC { uint256 hashConfirm = uint256(keccak256(abi.encode(_tradeId, "terminate", -_terminationPayment, terminationTerms))); require(pendingRequests[hashConfirm] == pendingRequestParty, "Confirmation of termination failed due to wrong party or missing request"); delete pendingRequests[hashConfirm]; - mutuallyTerminated = true; - terminationPayment = _terminationPayment; - emit TradeTerminationConfirmed(msg.sender, _tradeId, -_terminationPayment, terminationTerms); - /* Trigger final Settlement */ - address initiator = msg.sender; - tradeState = TradeState.Valuation; - emit TradeSettlementRequest(initiator, tradeData, settlementData[settlementData.length - 1]); + emit TradeTerminationConfirmed(msg.sender, _tradeId, terminationPayment, terminationTerms); + /* Trigger Termination Payment Amount */ + address payerAddress = terminationPayment > 0 ? otherParty(receivingParty) : receivingParty; + uint256 absPaymentAmount = uint256(abs(_terminationPayment)); + setTradeState(TradeState.InTermination); + processTradeAfterMutualTermination(payerAddress,absPaymentAmount,terminationTerms); + } /* @@ -227,49 +225,63 @@ abstract contract SDC is ISDC { emit TradeTerminationCanceled(msg.sender, _tradeId, terminationTerms); } - function processTradeAfterConfirmation(address upfrontPayer, uint256 upfrontPayment) virtual internal; - /* - * Utilities - */ + * Booking of the upfrontPayment and implementation specific setups of margin buffers / wallets. + */ + function processTradeAfterConfirmation(address upfrontPayer, uint256 upfrontPayment, string memory initialSettlementData) virtual internal; - /** - * Absolute value of an integer + /* + * Booking of the terminationAmount and implementation specific cleanup of margin buffers / wallets. */ - function abs(int x) internal pure returns (int256) { - return x >= 0 ? x : -x; - } + function processTradeAfterMutualTermination(address terminationFeePayer, uint256 terminationAmount, string memory terminationData) virtual internal; - /** - * Maximum value of two integers + /* + * Management of Trade States */ - function max(int a, int b) internal pure returns (int256) { - return a > b ? a : b; + function inStateIncepted() public view returns (bool) { return tradeState == TradeState.Incepted; } + function inStateConfirmed() public view returns (bool) { return tradeState == TradeState.Confirmed; } + function inStateSettled() public view returns (bool) { return tradeState == TradeState.Settled; } + function inStateTransfer() public view returns (bool) { return tradeState == TradeState.InTransfer; } + function inStateTermination() public view returns (bool) { return tradeState == TradeState.InTermination; } + function inStateTerminated() public view returns (bool) { return tradeState == TradeState.Terminated; } + + function getTradeState() public view returns (TradeState) { + return tradeState; } - /** - * Minimum value of two integers - */ - function min(int a, int b) internal pure returns (int256) { - return a < b ? a : b; + function setTradeState(TradeState newState) internal { + if ( newState == TradeState.Incepted && tradeState != TradeState.Inactive) + revert("Provided Trade state is not allowed"); + if ( newState == TradeState.Confirmed && tradeState != TradeState.Incepted) + revert("Provided Trade state is not allowed"); + if ( newState == TradeState.InTransfer && !(tradeState == TradeState.Confirmed || tradeState == TradeState.Valuation) ) + revert("Provided Trade state is not allowed"); + if ( newState == TradeState.Valuation && tradeState != TradeState.Settled) + revert("Provided Trade state is not allowed"); + if ( newState == TradeState.InTermination && !(tradeState == TradeState.InTransfer || tradeState == TradeState.Settled ) ) + revert("Provided Trade state is not allowed"); + tradeState = newState; } + /* + * Upfront and termination payments. + */ - function getTokenAddress() public view returns(address) { - return address(settlementToken); + function getReceivingParty() public view returns (address) { + return receivingParty; } - function getTradeState() public view returns (TradeState) { - return tradeState; + function getUpfrontPayment() public view returns (int) { + return upfrontPayment; } - /** - * Other party - */ - function otherParty(address party) internal view returns (address) { - return (party == party1 ? party2 : party1); + function getTerminationPayment() public view returns (int) { + return terminationPayment; } + /* + * Trade Specification (ID, Token, Data) + */ function getTradeID() public view returns (string memory) { return tradeID; @@ -279,9 +291,43 @@ abstract contract SDC is ISDC { tradeID= _tradeID; } + function getTokenAddress() public view returns(address) { + return address(settlementToken); + } + function getTradeData() public view returns (string memory) { return tradeData; } + /* + * Utilities (internal) + */ + + /** + * Other party + */ + function otherParty(address party) internal view returns (address) { + return (party == party1 ? party2 : party1); + } + /** + * Maximum value of two integers + */ + function max(int a, int b) internal pure returns (int256) { + return a > b ? a : b; + } + + /** + * Minimum value of two integers + */ + function min(int a, int b) internal pure returns (int256) { + return a < b ? a : b; + } + + /** + * Absolute value of an integer + */ + function abs(int x) internal pure returns (int256) { + return x >= 0 ? x : -x; + } } \ No newline at end of file diff --git a/assets/erc-6123/contracts/SDCPledgedBalance.sol b/assets/erc-6123/contracts/SDCPledgedBalance.sol index 17bd7edfe0..357ba86f1a 100644 --- a/assets/erc-6123/contracts/SDCPledgedBalance.sol +++ b/assets/erc-6123/contracts/SDCPledgedBalance.sol @@ -37,50 +37,29 @@ import "./ERC20Settlement.sol"; contract SDCPledgedBalance is SDC { + struct MarginRequirement { uint256 buffer; uint256 terminationFee; } - mapping(address => MarginRequirement) private marginRequirements; // Storage of M and P per counterparty address + int256[] private settlementAmounts; + string[] private settlementData; + constructor( address _party1, address _party2, address _settlementToken, - uint256 _initialBuffer, // m - uint256 _initalTerminationFee // p + uint256 _initialBuffer, // m + uint256 _initalTerminationFee // p ) SDC(_party1,_party2,_settlementToken) { marginRequirements[party1] = MarginRequirement(_initialBuffer, _initalTerminationFee); marginRequirements[party2] = MarginRequirement(_initialBuffer, _initalTerminationFee); } - function processTradeAfterConfirmation(address upfrontPayer, uint256 upfrontPayment) override internal{ - uint256 marginRequirementParty1 = uint(marginRequirements[party1].buffer + marginRequirements[party1].terminationFee ); - uint256 marginRequirementParty2 = uint(marginRequirements[party2].buffer + marginRequirements[party2].terminationFee ); - uint256 requiredBalanceParty1 = marginRequirementParty1 + (upfrontPayer==party1 ? upfrontPayment : 0); - uint256 requiredBalanceParty2 = marginRequirementParty2 + (upfrontPayer==party2 ? upfrontPayment : 0); - bool isAvailableParty1 = (settlementToken.balanceOf(party1) >= requiredBalanceParty1) && (settlementToken.allowance(party1, address(this)) >= requiredBalanceParty1); - bool isAvailableParty2 = (settlementToken.balanceOf(party2) >= requiredBalanceParty2) && (settlementToken.allowance(party2, address(this)) >= requiredBalanceParty2); - if (isAvailableParty1 && isAvailableParty2){ // Pre-Conditions: M + P needs to be locked (i.e. pledged) - address[] memory from = new address[](3); - address[] memory to = new address[](3); - uint256[] memory amounts = new uint256[](3); - from[0] = party1; to[0] = address(this); amounts[0] = marginRequirementParty1; - from[1] = party2; to[1] = address(this); amounts[1] = marginRequirementParty2; - from[2] = upfrontPayer; to[2] = otherParty(upfrontPayer); amounts[2] = upfrontPayment; - uint256 transactionID = uint256(keccak256(abi.encodePacked(from,to,amounts))); - tradeState = TradeState.InTransfer; - settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); // Atomic Transfer - } - else { - tradeState = TradeState.Inactive; - emit TradeTerminated("Insufficient Balance or Allowance"); - } - } - /* * Settlement can be initiated when margin accounts are locked, a valuation request event is emitted containing tradeData and valuationViewParty * Changes Process State to Valuation&Settlement @@ -88,7 +67,7 @@ contract SDCPledgedBalance is SDC { */ function initiateSettlement() external override onlyCounterparty onlyWhenSettled { address initiator = msg.sender; - tradeState = TradeState.Valuation; + setTradeState(TradeState.Valuation); emit TradeSettlementRequest(initiator, tradeData, settlementData[settlementData.length - 1]); } @@ -98,92 +77,124 @@ contract SDCPledgedBalance is SDC { * Checks Settlement amount according to valuationViewParty: If SettlementAmount is > 0, valuationViewParty receives * can be called only when ProcessState = ValuationAndSettlement */ - function performSettlement(int256 settlementAmount, string memory _settlementData) onlyWhenValuation external override { - - if (mutuallyTerminated){ - settlementAmount = settlementAmount + terminationPayment; - } - + (address settlementPayer,uint256 transferAmount) = determineTransferAmountAndPayerAddress(settlementAmount); + int cappedSettlementAmount = settlementPayer == receivingParty ? -int256(transferAmount) : int256(transferAmount); settlementData.push(_settlementData); - settlementAmounts.push(settlementAmount); + settlementAmounts.push(cappedSettlementAmount); // save the capped settlement amount + uint256 transactionID = uint256(keccak256(abi.encodePacked(settlementPayer,otherParty(settlementPayer), transferAmount, block.timestamp))); + address[] memory from = new address[](1); + address[] memory to = new address[](1); + uint256[] memory amounts = new uint256[](1); + from[0] = settlementPayer; to[0] = otherParty(settlementPayer); amounts[0] = transferAmount; + emit TradeSettlementPhase(); + setTradeState(TradeState.InTransfer); + settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); + } - uint256 transferAmount; - address settlementPayer; - (settlementPayer, transferAmount) = determineTransferAmountAndPayerAddress(settlementAmount); - - if (settlementToken.balanceOf(settlementPayer) >= transferAmount && - settlementToken.allowance(settlementPayer,address(this)) >= transferAmount) { /* Good case: Balances are sufficient and token has enough approval */ - uint256 transactionID = uint256(keccak256(abi.encodePacked(settlementPayer,otherParty(settlementPayer), transferAmount))); - emit TradeSettlementPhase(); - tradeState = TradeState.InTransfer; - address[] memory from = new address[](1); - address[] memory to = new address[](1); - uint256[] memory amounts = new uint256[](1); - from[0] = settlementPayer; to[0] = otherParty(settlementPayer); amounts[0] = transferAmount; - tradeState = TradeState.InTransfer; - settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); + /* + * afterTransfer processes SDC depending on success of the respective payment and depending on the current trade state + * Good Case: state will be settled, failed settlement will trigger the pledge balance transfer and termination + */ + function afterTransfer(bool success, uint256 transactionHash) external override { + if ( inStateConfirmed()){ + if (success){ + setTradeState(TradeState.Settled); + emit TradeActivated(getTradeID()); + } + else{ + setTradeState(TradeState.Terminated); + emit TradeTerminated("Upfront Transfer Failure"); + } } - else { /* Bad Case: Process termination by booking from own balance */ - tradeState = TradeState.InTransfer; - _processAfterTransfer(false); + else if ( inStateTransfer() ){ + if (success){ + setTradeState(TradeState.Settled); + emit TradeSettled("Settlement Settled - Pledge Transfer"); + } + else{ // Settlement & Pledge Case: transferAmount is transferred from SDC balance (i.e. pledged balance). + int256 settlementAmount = settlementAmounts[settlementAmounts.length-1]; + setTradeState(TradeState.InTermination); + processTerminationWithPledge(settlementAmount); + emit TradeTerminated("Settlement Failed - Pledge Transfer"); + } } + else if( inStateTermination() ){ + if (success){ + setTradeState(TradeState.Terminated); + emit TradeTerminated("Trade terminated sucessfully"); + } + else{ + emit TradeTerminated("Mutual Termination failed - Pledge Transfer"); + processTerminationWithPledge(getTerminationPayment()); + } + } + else + revert("Trade State does not allow to call 'afterTransfer'"); } + /* + * internal function which determines the capped settlement amount and poyer address + */ function determineTransferAmountAndPayerAddress(int256 settlementAmount) internal view returns(address, uint256) { address settlementReceiver = settlementAmount > 0 ? receivingParty : otherParty(receivingParty); address settlementPayer = otherParty(settlementReceiver); uint256 transferAmount; if (settlementAmount > 0) - transferAmount = uint256(abs(min( settlementAmount, int(marginRequirements[settlementPayer].buffer)))); + transferAmount = uint256(abs(min( settlementAmount, int256(marginRequirements[settlementPayer].buffer)))); else - transferAmount = uint256(abs(max( settlementAmount, -int(marginRequirements[settlementReceiver].buffer)))); + transferAmount = uint256(abs(max( settlementAmount, -int256(marginRequirements[settlementReceiver].buffer)))); return (settlementPayer,transferAmount); } - function afterTransfer(uint256 /* transactionHash */, bool success) external override onlyWhenInTransfer { - // Note: parameter transactionHash currenty unused - emit TradeSettled(); - _processAfterTransfer(success); + /* + * internal function which pepares the settlement tranfer after confirmation. + * Batched Transfer consists of Upfront Payment and Initial Prefunding to SDC Address + */ + + function processTradeAfterConfirmation(address upfrontPayer, uint256 upfrontPayment, string memory initialSettlementData) override internal{ + settlementAmounts.push(0); + settlementData.push(initialSettlementData); + address[] memory from = new address[](3); + address[] memory to = new address[](3); + uint256[] memory amounts = new uint256[](3); + from[0] = party1; to[0] = address(this); amounts[0] = uint(marginRequirements[party1].buffer + marginRequirements[party1].terminationFee ); + from[1] = party2; to[1] = address(this); amounts[1] = uint(marginRequirements[party2].buffer + marginRequirements[party2].terminationFee ); + from[2] = upfrontPayer; to[2] = otherParty(upfrontPayer); amounts[2] = upfrontPayment; + uint256 transactionID = uint256(keccak256(abi.encodePacked(from,to,amounts))); + settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); // Batched Transfer } - function _processAfterTransfer(bool success) internal{ - if(success){ - emit TradeSettled(); - if (tradeState == TradeState.Terminated || mutuallyTerminated){ - tradeState = TradeState.Inactive; - } - else{ - tradeState = TradeState.Settled; - } - } - else{ // TRANSFER HAS FAILED - if (settlementData.length == 1){ // Case after confirmTrade where Transfer of upfront has failed - tradeState = TradeState.Inactive; - emit TradeTerminated("Initial Upfront Transfer fail - Trade Inactive"); - } - else{ - // Settlement & Pledge Case: transferAmount is transferred from SDC balance (i.e. pledged balance). - int256 settlementAmount = settlementAmounts[settlementAmounts.length-1]; - uint256 transferAmount; - address settlementPayer; - (settlementPayer, transferAmount) = determineTransferAmountAndPayerAddress(settlementAmount); - address settlementReceiver = otherParty(settlementPayer); - settlementToken.approve(settlementPayer,uint256(marginRequirements[settlementPayer].buffer - transferAmount)); // Release Buffers - settlementToken.approve(settlementReceiver,uint256(marginRequirements[settlementReceiver].buffer)); // Release Buffers - - // Do Pledge Transfer from own balances including termination fee - tradeState = TradeState.Terminated; - emit TradeTerminated("Trade terminated due to regular settlement failure"); - address[] memory to = new address[](2); - uint256[] memory amounts = new uint256[](2); - to[0] = settlementReceiver; amounts[0] = uint256(transferAmount); - to[1] = settlementReceiver; amounts[1] = uint256(marginRequirements[settlementPayer].terminationFee); - uint256 transactionID = uint256(keccak256(abi.encodePacked(to,amounts))); - settlementToken.checkedBatchTransfer(to,amounts,transactionID); - } - } + /* + * internal function which processes mutual termination, transfers termination payment and releases pledged balances from sdc address + */ + function processTradeAfterMutualTermination(address terminationFeePayer, uint256 terminationAmount, string memory terminationData) override internal{ + settlementAmounts.push(0); // termination payment is saved separately + settlementData.push(terminationData); + address[] memory from = new address[](3); + address[] memory to = new address[](3); + uint256[] memory amounts = new uint256[](3); + from[0] = address(this); to[0] = party1; amounts[0] = uint(marginRequirements[party1].buffer + marginRequirements[party1].terminationFee ); // Release buffers + from[1] = address(this); to[1] = party2; amounts[1] = uint(marginRequirements[party2].buffer + marginRequirements[party2].terminationFee ); // Release buffers + from[2] = terminationFeePayer; to[2] = otherParty(terminationFeePayer); amounts[2] = terminationAmount; + uint256 transactionID = uint256(keccak256(abi.encodePacked(from,to,amounts))); + settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); // Batched Transfer } + + /* function which perfoms the "Pledged Booking" in case of failed settlement, transferring open settlement amount as well as termination fee from sdc's own balance + */ + function processTerminationWithPledge(int256 settlementAmount) internal{ + (address settlementPayer, uint256 transferAmount) = determineTransferAmountAndPayerAddress(settlementAmount); + address settlementReceiver = otherParty(settlementPayer); + address[] memory to = new address[](3); + uint256[] memory amounts = new uint256[](3); + to[0] = settlementReceiver; amounts[0] = transferAmount+marginRequirements[settlementPayer].terminationFee; // Settlement from Own Balance + to[1] = settlementReceiver; amounts[1] = marginRequirements[settlementReceiver].terminationFee + marginRequirements[settlementReceiver].buffer; // Release + to[2] = settlementPayer; amounts[2] = marginRequirements[settlementPayer].buffer-transferAmount; // Release of Buffer + uint256 transactionID = uint256(keccak256(abi.encodePacked(to,amounts))); + settlementToken.checkedBatchTransfer(to,amounts,transactionID); + } + } diff --git a/assets/erc-6123/doc/sequence.puml b/assets/erc-6123/doc/sequence.puml index 5ff19b5c7a..ea04005b0e 100644 --- a/assets/erc-6123/doc/sequence.puml +++ b/assets/erc-6123/doc/sequence.puml @@ -27,8 +27,6 @@ CP1 ->SettlementToken: allocate balances CP2 ->SettlementToken: allocate balances CP1 ->SDC: tx 'deploy' a SDC with token address activate SDC -CP1 ->SettlementToken: tx set 'allowance' for SDC address -CP2 ->SettlementToken: tx set 'allowance' for SDC address CP1 ->SDC: tx 'inceptTrade' SDC-->EventHandler: emit TradeIncepted @@ -71,7 +69,7 @@ else success else fail SDC->SettlementToken: tx 'transfer' Settlement Amount from SDC Balance to Receiving Party SDC->SettlementToken: tx 'transfer' Termination Fee from SDC Balance to Receiving Party - SDC->SettlementToken: tx 'approve' - Unlock remaing Party Balances + SDC->SettlementToken: tx 'transfer' - Release remainigBalances to parties == TradeState 'Terminated' == end diff --git a/assets/erc-6123/package.json b/assets/erc-6123/package.json index 24d9974fb7..19e85871df 100644 --- a/assets/erc-6123/package.json +++ b/assets/erc-6123/package.json @@ -1,6 +1,6 @@ { "name": "@finmath.net/sdc", - "version": "0.3.1", + "version": "0.4.0", "description": "Solidity Smart Derivative Contracts", "author": "Christian Fries, Peter Kohl-Landgraf, Alexandros Korpis", "license": "ISC", diff --git a/assets/erc-6123/test/SDCTests.js b/assets/erc-6123/test/SDCTests.js index b21ff704c4..dececef6c7 100644 --- a/assets/erc-6123/test/SDCTests.js +++ b/assets/erc-6123/test/SDCTests.js @@ -13,18 +13,19 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { Valuation: 3, InTransfer: 4, Settled: 5, - Terminated: 6 + InTermination: 6, + Terminated: 7 }; const abiCoder = new AbiCoder(); const trade_data = "here are the trade specification { counterparty2 = _counterparty2; ERC20Factory = await ethers.getContractFactory("ERC20Settlement"); SDCFactory = await ethers.getContractFactory("SDCPledgedBalance"); - token = await ERC20Factory.deploy(); - await token.deployed(); + //oken = await ERC20Factory.deploy(); + // await token.deployed(); }); - it("Initial minting and approvals for SDC", async () => { - await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); - await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); - }); - it("Counterparties incept and confirm a trade successfully, upfront is transferred", async () => { + + it("1. Counterparties incept and confirm a trade successfully, Upfront is transferred from CP1 to CP2", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+marginBufferAmount); - await token.connect(counterparty2).approve(sdc.address,terminationFee+marginBufferAmount+upfront); let trade_id =""; - const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, -upfront, "initialMarketData"); await expect(incept_call).to.emit(sdc, "TradeIncepted"); - const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, -upfront, "initialMarketData"); + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, upfront, "initialMarketData"); await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); let trade_state = await sdc.connect(counterparty1).getTradeState(); await expect(trade_state).equal(TradeState.Settled); + let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + console.log("Balance for SDC-Address: %s", sdc_balance); + await expect(sdc_balance).equal(2*(terminationFee+marginBufferAmount)); + await expect(cp1_balance).equal(initialLiquidityBalance-upfront-terminationFee-marginBufferAmount); + await expect(cp2_balance).equal(initialLiquidityBalance+upfront-terminationFee-marginBufferAmount); }); - it("Counterparty incepts and cancels trade successfully", async () => { + it("2a. CP1 is receiving party and pays initial Upfront (no buffers)", async () => { + let token = await ERC20Factory.deploy(); + let upfront1 = 150; + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,0,0); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, -upfront1, "initialMarketData"); + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, upfront1, "initialMarketData"); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(cp1_balance).equal(initialLiquidityBalance-upfront1); + await expect(cp2_balance).equal(initialLiquidityBalance+upfront1); + }); + + it("2b. CP1 is paying party and receives initial Upfront (no buffers)", async () => { + let token = await ERC20Factory.deploy(); + let upfront1 = 150; + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,0,0); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, -1, upfront1, "initialMarketData"); + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, 1, -upfront1, "initialMarketData"); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(cp1_balance).equal(initialLiquidityBalance+upfront1); + await expect(cp2_balance).equal(initialLiquidityBalance-upfront1); + }); + + it("2c. CP2 is paying party and pays initial Upfront (no buffers)", async () => { + let token = await ERC20Factory.deploy(); + let upfront1 = 150; + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,0,0); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront1, "initialMarketData"); + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, -upfront1, "initialMarketData"); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(cp1_balance).equal(initialLiquidityBalance+upfront1); + await expect(cp2_balance).equal(initialLiquidityBalance-upfront1); + }); + + it("3. Counterparty incepts and cancels trade successfully", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+marginBufferAmount); - await token.connect(counterparty2).approve(sdc.address,terminationFee+marginBufferAmount+upfront); let trade_id =""; const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); await expect(incept_call).to.emit(sdc, "TradeIncepted"); @@ -80,87 +125,126 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { await expect(trade_state).equal(TradeState.Inactive); }); - it("Not enough approval to transfer upfront payment", async () => { - let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+marginBufferAmount); - await token.connect(counterparty2).approve(sdc.address,terminationFee+marginBufferAmount); - const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); - await expect(incept_call).to.emit(sdc, "TradeIncepted"); - const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, -upfront, "initialMarketData"); - await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); - let trade_state = await sdc.connect(counterparty1).getTradeState(); - await expect(trade_state).equal(TradeState.Inactive); - }); + it("4. Not enough balance to transfer upfront payment", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - it("Trade Matching fails", async () => { - let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+marginBufferAmount); - await token.connect(counterparty2).approve(sdc.address,terminationFee+marginBufferAmount); - const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); - await expect(incept_call).to.emit(sdc, "TradeIncepted"); - const confirm_call = sdc.connect(counterparty2).confirmTrade(counterparty1.address, "none", -1, -upfront, "initialMarketData23"); - await expect(confirm_call).to.be.revertedWith("Confirmation fails due to inconsistent trade data or wrong party address"); - }); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 2*initialLiquidityBalance, "initialMarketData"); + await expect(incept_call).to.emit(sdc, "TradeIncepted"); + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, -2*initialLiquidityBalance, "initialMarketData"); + await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); + let trade_state = await sdc.connect(counterparty1).getTradeState(); + await expect(trade_state).equal(TradeState.Terminated); + let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(sdc_balance).equal(0); + await expect(cp1_balance).equal(initialLiquidityBalance); + await expect(cp2_balance).equal(initialLiquidityBalance); + }); - it("Trade cancellation fails due to wrong party calling cancel", async () => { - let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+marginBufferAmount); - await token.connect(counterparty2).approve(sdc.address,terminationFee+marginBufferAmount); - const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); - await expect(incept_call).to.emit(sdc, "TradeIncepted"); - const confirm_call = sdc.connect(counterparty2).cancelTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); - await expect(confirm_call).to.be.revertedWith("Cancellation fails due to inconsistent trade data or wrong party address"); - }); + it("5. Trade Matching fails", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); + await expect(incept_call).to.emit(sdc, "TradeIncepted"); + const confirm_call = sdc.connect(counterparty2).confirmTrade(counterparty1.address, "none", -1, -upfront, "initialMarketData23"); + await expect(confirm_call).to.be.revertedWith("Confirmation fails due to inconsistent trade data or wrong party address"); + }); - it("Trade cancellation fails due to wrong arguments", async () => { - let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+marginBufferAmount); - await token.connect(counterparty2).approve(sdc.address,terminationFee+marginBufferAmount); - const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); - await expect(incept_call).to.emit(sdc, "TradeIncepted"); - const confirm_call = sdc.connect(counterparty1).cancelTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData23"); - await expect(confirm_call).to.be.revertedWith("Cancellation fails due to inconsistent trade data or wrong party address"); - }); + it("6. Trade cancellation fails due to wrong party calling cancel", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); + await expect(incept_call).to.emit(sdc, "TradeIncepted"); + const confirm_call = sdc.connect(counterparty2).cancelTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); + await expect(confirm_call).to.be.revertedWith("Cancellation fails due to inconsistent trade data or wrong party address"); + }); - it("Counterparties incept and confirm a trade successfully, upfront is transferred, trade is terminated", async () => { + it("7. Trade cancellation fails due to wrong arguments", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+marginBufferAmount); - await token.connect(counterparty2).approve(sdc.address,terminationFee+marginBufferAmount+upfront); - // Incept trade (and fetch tradeId) + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); + await expect(incept_call).to.emit(sdc, "TradeIncepted"); + const confirm_call = sdc.connect(counterparty1).cancelTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData23"); + await expect(confirm_call).to.be.revertedWith("Cancellation fails due to inconsistent trade data or wrong party address"); + }); + + it("8. Counterparties incept and confirm, upfront is transferred from CP2 to CP1, Trade is terminated with Payment from CP2 to CP1", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); const receipt = await incept_call.wait(); const event = receipt.events.find(event => event.event === 'TradeIncepted'); const trade_id = event.args[1]; - const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, -upfront, "initialMarketData"); await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); - const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, terminationPayment, "terminationTerms"); await expect(terminate_call).to.emit(sdc, "TradeTerminationRequest"); - const confirm_terminate_call = await sdc.connect(counterparty2).confirmTradeTermination(trade_id, -terminationPayment, "terminationTerms"); await expect(confirm_terminate_call).to.emit(sdc, "TradeTerminationConfirmed"); let trade_state = await sdc.connect(counterparty1).getTradeState(); - await expect(trade_state).equal(TradeState.Valuation); + await expect(trade_state).equal(TradeState.Terminated); + let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(sdc_balance).equal(0); + await expect(cp1_balance).equal(initialLiquidityBalance+upfront+terminationPayment); + await expect(cp2_balance).equal(initialLiquidityBalance-upfront-terminationPayment); }); - it("Successful Settlement", async () => { + it("9a. CP1 is Receiving Party, Trade-Termination is incepted by CP2 which receives the termination payment from CP1", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); + const receipt = await incept_call.wait(); + const event = receipt.events.find(event => event.event === 'TradeIncepted'); + const trade_id = event.args[1]; + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); + const terminate_call = await sdc.connect(counterparty2).requestTradeTermination(trade_id, -terminationPayment, "terminationTerms"); + const confirm_terminate_call = await sdc.connect(counterparty1).confirmTradeTermination(trade_id, +terminationPayment, "terminationTerms"); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(cp1_balance).equal(initialLiquidityBalance-terminationPayment); + await expect(cp2_balance).equal(initialLiquidityBalance+terminationPayment); + }); + it("9b. CP1 is Receiving Party, Trade-Termination is incepted by CP1 which pays the termination payment to CP2", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); + const receipt = await incept_call.wait(); + const event = receipt.events.find(event => event.event === 'TradeIncepted'); + const trade_id = event.args[1]; + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); + const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, -terminationPayment, "terminationTerms"); + const confirm_terminate_call = await sdc.connect(counterparty2).confirmTradeTermination(trade_id, +terminationPayment, "terminationTerms"); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(cp1_balance).equal(initialLiquidityBalance-terminationPayment); + await expect(cp2_balance).equal(initialLiquidityBalance+terminationPayment); + }); + + it("10. Successful Inception with Upfront transferred from CP2 to CP1 + successful settlement transferred from CP1 to CP2", async () => { + let settlementAmount = -245; + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); - await sdc.deployed(); -// console.log("SDC Address: %s", sdc.address); - await token.connect(counterparty1).approve(sdc.address,terminationFee+10*marginBufferAmount); //Approve for 10*margin amount - await token.connect(counterparty2).approve(sdc.address,terminationFee+10*marginBufferAmount+upfront); let trade_id =""; const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); await expect(incept_call).to.emit(sdc, "TradeIncepted"); @@ -168,11 +252,73 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); const initSettlementPhase = sdc.connect(counterparty2).initiateSettlement(); await expect(initSettlementPhase).to.emit(sdc, "TradeSettlementRequest"); - const balance_call = await token.connect(counterparty2).balanceOf(counterparty2.address); -// console.log("Balance: %s", balance_call); - const performSettlementCall = sdc.connect(counterparty1).performSettlement(1,"settlementData"); + + const performSettlementCall = sdc.connect(counterparty1).performSettlement(settlementAmount,"settlementData"); await expect(performSettlementCall).to.emit(sdc, "TradeSettlementPhase"); let trade_state = await sdc.connect(counterparty1).getTradeState(); await expect(trade_state).equal(TradeState.Settled); + let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(sdc_balance).equal(2*(terminationFee+marginBufferAmount)); + await expect(cp1_balance).equal(initialLiquidityBalance-terminationFee-marginBufferAmount+upfront+settlementAmount); + await expect(cp2_balance).equal(initialLiquidityBalance-terminationFee-marginBufferAmount-upfront-settlementAmount); + }); + + it("11. Failed settlement followed by Termination with Pledge Case", async () => { + let settlementAmount = -500; + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + let trade_id =""; + let upfront_max = initialLiquidityBalance - marginBufferAmount - terminationFee; + + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, -upfront_max, "initialMarketData"); + await expect(incept_call).to.emit(sdc, "TradeIncepted"); + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, +upfront_max, "initialMarketData"); + await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); + + const initSettlementPhase = sdc.connect(counterparty2).initiateSettlement(); + await expect(initSettlementPhase).to.emit(sdc, "TradeSettlementRequest"); + + const performSettlementCall = sdc.connect(counterparty1).performSettlement(settlementAmount,"settlementData"); + await expect(performSettlementCall).to.emit(sdc, "TradeSettlementPhase"); + let trade_state = await sdc.connect(counterparty1).getTradeState(); + let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + + await expect(trade_state).equal(TradeState.Terminated); + await expect(sdc_balance).equal(0); + await expect(cp1_balance).equal(marginBufferAmount+settlementAmount); + await expect(cp2_balance).equal(initialLiquidityBalance+upfront_max-settlementAmount+terminationFee); + + }); + + it("12. Failed Mutual Termination: Payment from CP1 to CP2 results in pledge case with capped termination fee amount being transferred", async () => { + let token = await ERC20Factory.deploy(); + await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); + await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); + let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); + const receipt = await incept_call.wait(); + const event = receipt.events.find(event => event.event === 'TradeIncepted'); + const trade_id = event.args[1]; + const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); + await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); + const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, 10000000, "terminationTerms"); + await expect(terminate_call).to.emit(sdc, "TradeTerminationRequest"); + const confirm_terminate_call = await sdc.connect(counterparty2).confirmTradeTermination(trade_id, -10000000, "terminationTerms"); + await expect(confirm_terminate_call).to.emit(sdc, "TradeTerminationConfirmed"); + let trade_state = await sdc.connect(counterparty1).getTradeState(); + await expect(trade_state).equal(TradeState.Terminated); + let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); + let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); + await expect(sdc_balance).equal(0); + await expect(cp1_balance).equal(initialLiquidityBalance+marginBufferAmount+terminationFee); + await expect(cp2_balance).equal(initialLiquidityBalance-marginBufferAmount-terminationFee); + }); }); \ No newline at end of file From c7f655702fe61c9f05e775ffaac5b1d011c5fcda Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:59:11 -0400 Subject: [PATCH 08/79] Update jekyll-label-bot.yml (#544) --- .github/workflows/jekyll-label-bot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jekyll-label-bot.yml b/.github/workflows/jekyll-label-bot.yml index 549c28c9b4..f5450c9a71 100644 --- a/.github/workflows/jekyll-label-bot.yml +++ b/.github/workflows/jekyll-label-bot.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: Pandapip1/jekyll-label-action@d0fd82c3cd118140a50843906845fca8e59a8b9e + - uses: Pandapip1/jekyll-label-action@753297a43dc77d48a8b92e5d66622c452a5247a9 with: token: ${{ secrets.GITHUB_TOKEN }} config-path: config/.jekyll-labels.yml From 10e5f3dd66b76aff10eba1c29dfa467fbc6edee0 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:06:49 -0400 Subject: [PATCH 09/79] Update jekyll-label-bot.yml --- .github/workflows/jekyll-label-bot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jekyll-label-bot.yml b/.github/workflows/jekyll-label-bot.yml index f5450c9a71..73307415ca 100644 --- a/.github/workflows/jekyll-label-bot.yml +++ b/.github/workflows/jekyll-label-bot.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: Pandapip1/jekyll-label-action@753297a43dc77d48a8b92e5d66622c452a5247a9 + - uses: Pandapip1/jekyll-label-action@4b7cce7588a8686f5146a8e12aab7269042057ce with: token: ${{ secrets.GITHUB_TOKEN }} config-path: config/.jekyll-labels.yml From 80c2da06e7258e7c0a4bc3ac479675ee3070dbcb Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Thu, 1 Aug 2024 10:21:53 +0200 Subject: [PATCH 10/79] Website: Refactor rename for events associated with settlement. Merged by EIP-Bot. --- ERCS/erc-6123.md | 8 ++--- assets/erc-6123/contracts/ISDC.sol | 33 +++++++++++++------ .../erc-6123/contracts/SDCPledgedBalance.sol | 6 ++-- assets/erc-6123/test/SDCTests.js | 8 ++--- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index 591bd4dcef..16ce2ce58f 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -173,20 +173,20 @@ Emitted when a Trade is activated event TradeActivated(string tradeId); ``` -### TradeSettlementRequest +### SettlementRequested Emitted when a settlement is requested. May trigger the settlement phase. ```solidity -event TradeSettlementRequest(address initiator, string tradeData, string lastSettlementData); +event SettlementRequested(address initiator, string tradeData, string lastSettlementData); ``` -### TradeSettlementPhase +### SettlementEvaluated Emitted when the settlement phase is started. ```solidity -event TradeSettlementPhase(); +event SettlementEvaluated(); ``` #### TradeTerminationRequest diff --git a/assets/erc-6123/contracts/ISDC.sol b/assets/erc-6123/contracts/ISDC.sol index e82b4d3a8c..90b299f72d 100644 --- a/assets/erc-6123/contracts/ISDC.sol +++ b/assets/erc-6123/contracts/ISDC.sol @@ -62,7 +62,11 @@ pragma solidity >=0.7.0 <0.9.0; */ interface ISDC { + /*------------------------------------------- EVENTS ---------------------------------------------------------------------------------------*/ + + /* Events related to trade inception */ + /** * @dev Emitted when a new trade is incepted from a eligible counterparty * @param initiator is the address from which trade was incepted @@ -85,6 +89,8 @@ interface ISDC { */ event TradeCanceled(address initiator, string tradeId); + /* Events related to activation and termination */ + /** * @dev Emitted when a confirmed trade is set to active - e.g. when termination fee amounts are provided * @param tradeId the trade identifier of the activated trade @@ -97,15 +103,22 @@ interface ISDC { */ event TradeTerminated(string cause); + /* Events related to the settlement process */ + /** * @dev Emitted when Settlement phase is initiated */ - event TradeSettlementPhase(); + event SettlementEvaluated(); /** * @dev Emitted when settlement process has been finished */ - event TradeSettled(string transactionData); + event SettlementTranfered(string transactionData); + + /** + * @dev Emitted when settlement process has been finished + */ + event SettlementFailed(string transactionData); /** * @dev Emitted when a settlement gets requested @@ -113,7 +126,9 @@ interface ISDC { * @param tradeData holding the stored trade data * @param lastSettlementData holding the settlementdata from previous settlement (next settlement will be the increment of next valuation compared to former valuation) */ - event TradeSettlementRequest(address initiator, string tradeData, string lastSettlementData); + event SettlementRequested(address initiator, string tradeData, string lastSettlementData); + + /* Events related to trade termination */ /** * @dev Emitted when a counterparty proactively requests an early termination of the underlying trade @@ -162,7 +177,7 @@ interface ISDC { /** * @notice Performs a matching of provided trade data and settlement data of a previous trade inception - * @dev emits a {TradeConfirmed} event if trade data match + * @dev emits a {TradeConfirmed} event if trade data match and emits a {TradeActivated} if trade becomes active or {TradeTerminated} if not * @param withParty is the party the confirmer wants to trade with * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml * @param position is the position the confirmer has in that trade (negative of the position the inceptor has in the trade) @@ -186,13 +201,13 @@ interface ISDC { /** * @notice Called to trigger a (maybe external) valuation of the underlying contract and afterwards the according settlement process - * @dev emits a {TradeSettlementRequest} + * @dev emits a {SettlementRequested} */ function initiateSettlement() external; /** * @notice Called to trigger according settlement on chain-balances callback for initiateSettlement() event handler - * @dev perform settlement checks, may initiate transfers and emits {TradeSettlementPhase} + * @dev perform settlement checks, may initiate transfers and emits {SettlementEvaluated} * @param settlementAmount the settlement amount. If settlementAmount > 0 then receivingParty receives this amount from other party. If settlementAmount < 0 then other party receives -settlementAmount from receivingParty. * @param settlementData. the tripple (product, previousSettlementData, settlementData) determines the settlementAmount. */ @@ -203,11 +218,10 @@ interface ISDC { * @notice May get called from outside to to finish a transfer (callback). The trade decides on how to proceed based on success flag * @param success tells the protocol whether transfer was successful * @param transactionData data associtated with the transfer, will be emitted via the events. - * @dev may emit a {TradeSettled} event or a {TradeTerminated} event + * @dev emit a {SettlementTranfered} or a {SettlementFailed} event. May emit a {TradeTerminated} event. */ function afterTransfer(bool success, uint256 transactionData) external; - /// Trade termination /** @@ -230,10 +244,9 @@ interface ISDC { /** * @notice Called from a party to confirm an incepted termination, which might trigger a final settlement before trade gets closed - * @dev emits a {TradeTerminationConfirmed} + * @dev emits a {TradeTerminationCanceled} * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml * @param terminationTerms the termination terms */ function cancelTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; - } diff --git a/assets/erc-6123/contracts/SDCPledgedBalance.sol b/assets/erc-6123/contracts/SDCPledgedBalance.sol index 357ba86f1a..e6a6732ee7 100644 --- a/assets/erc-6123/contracts/SDCPledgedBalance.sol +++ b/assets/erc-6123/contracts/SDCPledgedBalance.sol @@ -68,7 +68,7 @@ contract SDCPledgedBalance is SDC { function initiateSettlement() external override onlyCounterparty onlyWhenSettled { address initiator = msg.sender; setTradeState(TradeState.Valuation); - emit TradeSettlementRequest(initiator, tradeData, settlementData[settlementData.length - 1]); + emit SettlementRequested(initiator, tradeData, settlementData[settlementData.length - 1]); } /* @@ -87,7 +87,7 @@ contract SDCPledgedBalance is SDC { address[] memory to = new address[](1); uint256[] memory amounts = new uint256[](1); from[0] = settlementPayer; to[0] = otherParty(settlementPayer); amounts[0] = transferAmount; - emit TradeSettlementPhase(); + emit SettlementEvaluated(); setTradeState(TradeState.InTransfer); settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); } @@ -110,7 +110,7 @@ contract SDCPledgedBalance is SDC { else if ( inStateTransfer() ){ if (success){ setTradeState(TradeState.Settled); - emit TradeSettled("Settlement Settled - Pledge Transfer"); + emit SettlementTranfered("Settlement Settled - Pledge Transfer"); } else{ // Settlement & Pledge Case: transferAmount is transferred from SDC balance (i.e. pledged balance). int256 settlementAmount = settlementAmounts[settlementAmounts.length-1]; diff --git a/assets/erc-6123/test/SDCTests.js b/assets/erc-6123/test/SDCTests.js index dececef6c7..180231a0f3 100644 --- a/assets/erc-6123/test/SDCTests.js +++ b/assets/erc-6123/test/SDCTests.js @@ -251,10 +251,10 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, -upfront, "initialMarketData"); await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); const initSettlementPhase = sdc.connect(counterparty2).initiateSettlement(); - await expect(initSettlementPhase).to.emit(sdc, "TradeSettlementRequest"); + await expect(initSettlementPhase).to.emit(sdc, "SettlementRequested"); const performSettlementCall = sdc.connect(counterparty1).performSettlement(settlementAmount,"settlementData"); - await expect(performSettlementCall).to.emit(sdc, "TradeSettlementPhase"); + await expect(performSettlementCall).to.emit(sdc, "SettlementEvaluated"); let trade_state = await sdc.connect(counterparty1).getTradeState(); await expect(trade_state).equal(TradeState.Settled); let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); @@ -281,10 +281,10 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); const initSettlementPhase = sdc.connect(counterparty2).initiateSettlement(); - await expect(initSettlementPhase).to.emit(sdc, "TradeSettlementRequest"); + await expect(initSettlementPhase).to.emit(sdc, "SettlementRequested"); const performSettlementCall = sdc.connect(counterparty1).performSettlement(settlementAmount,"settlementData"); - await expect(performSettlementCall).to.emit(sdc, "TradeSettlementPhase"); + await expect(performSettlementCall).to.emit(sdc, "SettlementEvaluated"); let trade_state = await sdc.connect(counterparty1).getTradeState(); let sdc_balance = await token.connect(counterparty1).balanceOf(sdc.address); let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); From e21527a50060ab8c1bbfb0e4345e779a2504c91b Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Thu, 1 Aug 2024 11:06:15 +0200 Subject: [PATCH 11/79] Update ERC-6123: Refactor rename SDC.sol to SDCSingleTrade.sol Merged by EIP-Bot. --- ERCS/erc-6123.md | 5 +++-- assets/erc-6123/contracts/{SDC.sol => SDCSingleTrade.sol} | 0 ...DCPledgedBalance.sol => SDCSingleTradePledgedBalance.sol} | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename assets/erc-6123/contracts/{SDC.sol => SDCSingleTrade.sol} (100%) rename assets/erc-6123/contracts/{SDCPledgedBalance.sol => SDCSingleTradePledgedBalance.sol} (99%) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index 16ce2ce58f..43986463a8 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -238,7 +238,8 @@ The interface design and reference implementation are based on the following con - The interface specification is generic enough to handle the case that parties process one or even multiple financial transactions (on a netted base) - Usually, the valuation of financial trades (e.g. OTC Derivatives) will require advanced valuation methodology to determine the market value. This is why the concept might rely on an external market data source and hosted valuation algorithms - A pull-based valuation-based oracle pattern can be implemented by using the provided callback pattern (methods: `initiateSettlement`, `performSettlement`) -- The reference implementation `SDC.sol` is based on a state-machine pattern where the states also serve as guards (via modifiers) to check which method is allowed to be called at a particular given process and trade state +- The reference implementation `SDCSingleTrade.sol` considers a single trade and is based on a state-machine pattern where the states also serve as guards (via modifiers) to check which method is allowed to be called at a particular given process and trade state +- The interface allows the extension to multiple trades with common (netted) settlement. ### State diagram of trade and process states @@ -254,7 +255,7 @@ Life-cycle unit tests based on the sample implementation and usage of [ERC-20](. ## Reference Implementation -An abstract contract class SDC.sol as well as a full reference implementation SDCPledgedBalance.sol for an OTC-Derivative is provided and is based on the [ERC-20](./eip-20.md) token standard. +An abstract contract class `SDCSingleTrade.sol` for single trade SDCs as well as a full reference implementation SDCPledgedBalance.sol for an OTC-Derivative is provided and is based on the [ERC-20](./eip-20.md) token standard. See folder `/assets/contracts`, more explanation on the implementation is provided inline. ### Trade Data Specification (suggestion) diff --git a/assets/erc-6123/contracts/SDC.sol b/assets/erc-6123/contracts/SDCSingleTrade.sol similarity index 100% rename from assets/erc-6123/contracts/SDC.sol rename to assets/erc-6123/contracts/SDCSingleTrade.sol diff --git a/assets/erc-6123/contracts/SDCPledgedBalance.sol b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol similarity index 99% rename from assets/erc-6123/contracts/SDCPledgedBalance.sol rename to assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol index e6a6732ee7..0268780714 100644 --- a/assets/erc-6123/contracts/SDCPledgedBalance.sol +++ b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CC0-1.0 pragma solidity >=0.8.0 <0.9.0; -import "./SDC.sol"; +import "./SDCSingleTrade.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "./ERC20Settlement.sol"; From e9480178aff5750f2acbf7252b1aef903805d45d Mon Sep 17 00:00:00 2001 From: nand2 Date: Thu, 1 Aug 2024 15:12:05 +0200 Subject: [PATCH 12/79] Update ERC-6860: Add the fragment part to the URL definition. Merged by EIP-Bot. --- ERCS/erc-6860.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-6860.md b/ERCS/erc-6860.md index 092e988adf..a79ddac86e 100644 --- a/ERCS/erc-6860.md +++ b/ERCS/erc-6860.md @@ -38,7 +38,7 @@ This specification uses the Augmented Backus-Naur Form (ABNF) notation of [RFC 2 A Web3 URL is an ASCII string in the following form : ``` -web3URL = schema "://" [ userinfo "@" ] contractName [ ":" chainid ] pathQuery +web3URL = schema "://" [ userinfo "@" ] contractName [ ":" chainid ] pathQuery [ "#" fragment ] schema = "w3" / "web3" userinfo = address ``` @@ -69,6 +69,12 @@ pathQuery = mPathQuery ; path+query for manual mode **pathQuery**, made of the path and optional query, will have a different structure whether the resolve mode is "manual" or "auto". +``` +fragment = *VCHAR +``` + +**fragment**, like in HTTP URLs, is a string of characters meant to refer to a resource, and is not transmitted to the smart contract. + ``` web3UrlRef = web3URL / relativeWeb3URL @@ -286,7 +292,7 @@ The protocol will find the address of **vitalik.eth** from ENS on chainid 1 (Mai ### Appendix A: Complete ABNF for Web3 URLs ``` -web3URL = schema "://" [ userinfo "@" ] contractName [ ":" chainid ] pathQuery +web3URL = schema "://" [ userinfo "@" ] contractName [ ":" chainid ] pathQuery [ "#" fragment ] schema = "w3" / "web3" userinfo = address contractName = address @@ -295,6 +301,7 @@ chainid = %x31-39 *DIGIT pathQuery = mPathQuery ; path+query for manual mode / aPathQuery ; path+query for auto mode +fragment = *VCHAR web3UrlRef = web3URL / relativeWeb3URL From 590bf774646f4facd5b3e60a6828045b2d67e7f0 Mon Sep 17 00:00:00 2001 From: galimba Date: Thu, 1 Aug 2024 20:26:28 +0200 Subject: [PATCH 13/79] Update ERC-7208: prep Merged by EIP-Bot. --- ERCS/erc-7208.md | 286 +++--------------- assets/erc-7208/erc-7208-compat.md | 20 +- assets/erc-7208/erc-7208-overview.svg | 2 +- .../erc-7208/erc-7208-technical-overview.svg | 2 +- 4 files changed, 57 insertions(+), 253 deletions(-) diff --git a/ERCS/erc-7208.md b/ERCS/erc-7208.md index 3dd6fca0d5..8b4d1d3f23 100644 --- a/ERCS/erc-7208.md +++ b/ERCS/erc-7208.md @@ -1,7 +1,7 @@ --- eip: 7208 title: On-Chain Data Container -description: Abstracting logic away from storage +description: ERC interoperability by abstracting logic away from storage author: Rachid Ajaja , Alexandros Athanasopulos (@Xaleee), Pavel Rubin (@pash7ka), Sebastian Galimberti Romano (@galimba) discussions-to: https://ethereum-magicians.org/t/erc-7208-on-chain-data-container/14778 status: Draft @@ -15,22 +15,22 @@ requires: 165 -"On-chain Data Containers" (ODCs) are used for indexing and storing data in Smart Contracts called "Data Objects" (DOs). Information stored in Data Objects can be accessed and modified by implementing smart contracts called "Data Managers" (DMs). This ERC defines a series of interfaces for the separation of the storage of data from the implementation of the logic functions that govern such data. We introduce the interfaces for ODCs, the structures associated with DOs for abstracting storage, the DMs to access or modify the data, and finally the interfaces for compatibility Registries that enable Data Portability (horizontal mobility) between different implementations of this ERC. - +"On-chain Data Containers" (ODCs) are a series of interfaces used for indexing and managing data in Smart Contracts called "Data Object" (DO). Information stored in Data Objects can be accessed and modified by implementing smart contracts called "Data Manager" (DM). This ERC defines a series of interfaces for the separation of the storage of data from the implementation of the logic functions that govern such data. We introduce the interfaces for access management through "Data Index" (DI) implementations, the structures associated with "Data Points" (DP) for abstracting storage, the Data Managers to access or modify the data, and finally the "Data Point Registries" (DPR) interfaces for compatibility that enable data portability (horizontal mobility) between different implementations of this ERC. ## Motivation -As the Ethereum ecosystem grows, so does the demand for on-chain functionalities. The market encourages a desire for broader adoption and more complex systems, so there is a constant need for improved efficiency. We have seen times where the market hype has driven an explosion of new standard token proposals. While each standard serves its purpose, most often requires more flexibility to manage interoperability with other standards. +As the Ethereum ecosystem grows, so does the demand for on-chain functionalities. The market encourages a desire for broader adoption through more complex systems and there is a constant need for improved efficiency. We have seen times where the market hype has driven an explosion of new standard token proposals. While each standard serves its purpose, most often requires more flexibility to manage interoperability with other standards. + -While such diversity spurs innovation, different projects will implement their bespoke solutions for interoperability, resulting in a highly fragmented landscape. The lack of a standard mechanism for adapting tokenized across ERC standards is accentuating the interoperability issues. +The diversity of standards spurs innovation. Different projects will implement their bespoke solutions for interoperability. The absence of a unified adapter mechanism driving the interactions between assets issued under different ERC standards is causing interoperability issues. This, in turn, is leading to fragmentation. -We recognize there is no “one size fits all” solution to solve the standardization and interoperability challenges. Most assets - Fungible, Non-Fungible, Digital Twins, Real-world Assets, DePin, etc - have multiple mechanisms for representing them as on-chain tokens using different standard interfaces. However, for those assets to be exchanged, traded, or interacted with, protocols must implement compatibility with those standards before accessing and modifying the on-chain data. Moreover, the immutability of smart contracts plays a role in future-proofing their implementations by supporting new tokenization standards. A collaborative effort must be made to enable interaction between assets tokenized under different standards. The current ERC provides the tools for developing such On-chain Adapters. +We recognize there is no “one size fits all” solution to solve the standardization and interoperability challenges. Most assets - Fungible, Non-Fungible, Digital Twins, Real-world Assets, DePin, etc - have multiple mechanisms for representing them as on-chain tokens through the use of different standard interfaces. However, for those assets to be exchanged, traded, or interacted with, protocols must implement compatibility with those standards before accessing and modifying the on-chain data. Moreover, the immutability of smart contracts plays a role in future-proofing their implementations by supporting new tokenization standards. A collaborative effort must be made to enable interaction between assets tokenized under different standards. The current ERC provides the tools for developing such on-chain adapters. -We aim to abstract the on-chain data handling from both the logical implementation and the ERC interfaces exposing the underlying data. This EIP proposes a series of interfaces for storing and accessing data on-chain, codifying the underlying assets as generic "Data Points" that may be associated with multiple interoperable and even concurrent ERC interfaces. This proposal is designed to work by coexisting with previous and future token standards, providing a flexible, efficient, and coherent mechanism to manage asset interoperability. +We aim to abstract the on-chain data handling from the logical implementation and the ERC interfaces exposing the underlying data. The current ERC proposes a series of interfaces for storing and accessing data on-chain, codifying the underlying assets as generic "Data Points" that may be associated with multiple interoperable and even concurrent ERC interfaces. This proposal is designed to work by coexisting with previous and future token standards, providing a flexible, efficient, and coherent mechanism to manage asset interoperability. - **Data Abstraction**: We propose a standardized interface for enabling developers to separate the data storage code from the underlying token utility logic, reducing the need for supporting and implementing multiple inherited -and often clashing- interfaces to achieve asset compatibility. The data (and therefore the assets) can be stored independently of the logic that governs such data. @@ -46,30 +46,27 @@ We aim to abstract the on-chain data handling from both the logical implementati ### Terms +**Data Index Implementation**: One or many Smart Contracts implementing the Data Index interface, used for data access management through the indexing of Data Objects. -**ODC**: A uniquely identifiable data structure used for indexing Data Objects or storing Data Points. - -**ODC Implementation**: One or many Smart Contracts implementing the ODC access-management logic. - -**Data Point**: A uniquely identifiable unit of information. +**Data Point**: A uniquely identifiable unit of information indexed by a Data Index, managed by a Data Manager through a Data Object, and provided by a Data Point Registry. -**Data Object**: One or many Smart Contracts implementing the low-level storage management of stored Data Points +**Data Object**: One or many Smart Contracts implementing the low-level storage management of stored Data Points. -**Data Manager**: One or many Smart Contracts implementing the high-level logic and end-user interface for managing the Data Points. +**Data Manager**: One or many Smart Contracts implementing the high-level logic and end-user interfaces for managing Data Points. **Data Point Registry**: One or many Smart Contracts that define a space of compatible or interoperable Data Points. -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. +The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -### ODC Interface +### Data Index Interface - * ODC SHOULD manage internal IDs for each data container. - * ODC SHOULD manage the access of Data Managers to Data Objects. - * ODC SHOULD use the IODC interface: + * DataIndex SHOULD manage the access of Data Managers to Data Objects. + * DataIndex SHOULD manage internal IDs for each user. + * DataIndex SHOULD use the IDataIndex interface: ```solidity -interface IODC { +interface IDataIndex { /** * @notice Verifies if DataManager is allowed to write specific DataPoint on specific DataObject * @param dp Identifier of the DataPoint @@ -109,12 +106,15 @@ interface IODC { function write(address dobj, DataPoint dp, bytes4 operation, bytes calldata data) external returns(bytes memory); } ``` +The **Data Index** is a smart contract entrusted with access control. It is a gating mechanism for **Data Managers** to access **Data Objects**. If a **Data Manager** intends to access a **Data Point** (either by `read()`, `write()`, or any other method), the **Data Index** should be used for validating access to the data. + +The mechanism for ID managamenent determines a space of compatibility between implementations. ### Data Object Interface * Data Object SHOULD implement the logic directly related to handling the data stored on Data Points. - * Data Object SHOULD implement the logic for transfering management of its Data Points to a different ODC Implementation. + * Data Object SHOULD implement the logic for transfering management of its Data Points to a different Data Index Implementation. * Data Object SHOULD use the IDataObject interface: ```solidity @@ -138,18 +138,18 @@ interface IDataObject { function write(DataPoint dp, bytes4 operation, bytes calldata data) external returns(bytes memory); /** - * @notice Sets ODC Implementation + * @notice Sets DataIndex Implementation * @param dp Identifier of the DataPoint - * @param newImpl address of the new ODC implementation + * @param newImpl address of the new DataIndex implementation */ - function setOdcImplementation(DataPoint dp, address newImpl) external; + function setDIImplementation(DataPoint dp, address newImpl) external; } ``` +**Data Objects** are entrusted with the management of transactions that affect the storage of **Data Points**. -Data Objects can receive `read()` or `write()` requests when a Data Manager is requesting access to a Data Point. - -The function `setODCImplementation()` SHOULD enable the delegation of the the management function to an IODC implementation. +**Data Objects** can receive `read()`, `write()`, or any other custom requests from a **Data Manager** requesting access to a **Data Point**. +As such, **Data Objects** respond to a gating mechanism given by a single **Data Index**. The function `setDIImplementation()` SHOULD enable the delegation of the the management function to an `IDataIndex` implementation. ### Data Point Structure @@ -176,6 +176,8 @@ The function `setODCImplementation()` SHOULD enable the delegation of the the ma **/ ``` +**Data Points** are the low-level structure abstracting information. **Data Points** are allocated by a **Data Point Registry**, and this information should be stored within its internal structure. Each **Data Point** should have a unique identifier provided by the **Data Point Registry** when instantiated. + ### Data Point Registry Interface @@ -208,7 +210,7 @@ interface IDataPointRegistry { function transferOwnership(DataPoint dp, address newOwner) external; /** - * @notice Grant permission to grant/revoke other roles on the DataPoint inside an ODC Implementation + * @notice Grant permission to grant/revoke other roles on the DataPoint inside a Data Index Implementation * This is useful if DataManagers are deployed during lifecycle of the application. * @param dp DataPoint * @param account New admin @@ -217,7 +219,7 @@ interface IDataPointRegistry { function grantAdminRole(DataPoint dp, address account) external returns (bool); /** - * @notice Revoke permission to grant/revoke other roles on the DataPoint inside an ODC Implementation + * @notice Revoke permission to grant/revoke other roles on the DataPoint inside a Data Index Implementation * @param dp DataPoint * @param account Old admin * @dev If an owner revokes Admin role from himself, he can add it again @@ -226,6 +228,8 @@ interface IDataPointRegistry { function revokeAdminRole(DataPoint dp, address account) external returns (bool); } ``` +The **Data Point Registry** is a smart contract entrusted with **Data Point** access control. **Data Managers** may request the allocation of **Data Points** to the **Data Point Registry**. Access-control to those **Data Points** is also managed by the **Data Point Registry**. + ### Data Manager Contract @@ -236,7 +240,7 @@ interface IDataPointRegistry { * Data Manager MAY use multiple Data Points * Data Manager MAY implement the logic for requesting Data Points from a Data Point Registry. -Data Managers are independent smart contracts that implement the business logic. They can either `read()` from a DataObject address, and `write()` through an ODC Implementation managing the delegated storage of the Data Points. +**Data Managers** are independent smart contracts that implement the business logic or "high-level" data management. They can either `read()` from a **Data Object** address and `write()` through a **Data Index** Implementation managing the delegated storage of the **Data Points**. ## Rationale @@ -245,238 +249,38 @@ Data Managers are independent smart contracts that implement the business logic. The decision to encode Data Points as bytes32 data containers is primarily driven by flexibility and future-proofing. Using bytes32 allows for a wide range of data encodings. This provides the developer with many options to accommodate diverse use cases. Furthermore, as Ethereum and its standards continue to evolve, encoding as bytes32 ensures that the Standard Adapters can support future data types or structures without requiring significant changes to the standard adapter itself. The Data Point encoding should have a prefix so that the Data Object can efficiently identify compatibility issues when accessing the data storage. Additionally, the prefix should be used to find the Data Point Registry and verify admin access of the Data Point. The use of a suffix for identifying the Data Point Registry is also required, for the Data Object to quickly discard badly formed transactions that aim to use a Data Point from an unmatching Data Point Registry. -Data Manager implementations decide which Data Points they will be using. Their allocation is managed through a Data Point Registry, and the access to the Data Point is managed by passing through the ODC Implementation. +Data Manager implementations decide which Data Points they will be using. Their allocation is managed through a Data Point Registry, and the access to the Data Point is managed by passing through the Data Index Implementation. Data Objects being independent separate Smart Contracts that implement the same `read`/`write` interface for communicating with Data Managers is a decision mainly driven by the scalability of the system. Offering a simple interface for this 2-layer structure enables different applications to have their addresses for storage of data as well as assets. It is up to each implementation to manage access to this Data Point storage space. This enables a wide array of complex, dynamic, and interactive use cases to be implemented with multiple ERCs as well as other smart contracts. Data Objects offer flexibility in storing mutable on-chain data that can be modified as per the requirements of each specific use case. This enables the Data Managers to hold mutable states in delegated storage and reflect changes over time, providing a dynamic layer to the otherwise static nature of storage through most other standardized interfaces. -As the Data Points can be set to respond to a specific ODC implementation, Data Managers can decide to migrate the complete storage of a Data Object from one ODC implementation to another. -By leveraging multiple implementations of the IODC interface, this standard delivers a powerful framework that amplifies the potential of all ERCs (present and future). +As the Data Points can be set to respond to a specific Data Index implementation, Data Managers can decide to migrate the complete storage of a Data Object from one Data Index implementation to another. +By leveraging multiple implementations of the `IDataIndex` interface, this standard delivers a powerful framework that amplifies the potential of all ERCs (present and future). ## Backwards Compatibility -This ERC is intended to augment the functionality of existing token standards without introducing breaking changes. As such, it does not present any backwards compatibility issues. Already deployed ERCs can be wrapped as Data Points or owned in Vaults as Data Objects, and later exposed through any implementation of Data Managers. - -See Reference Implementation. - +This ERC is intended to augment the functionality of existing token standards without introducing breaking changes. As such, it does not present any backward compatibility issues. Already deployed tokens under other ERCs can be wrapped as Data Points and managed by Data Objects, and later exposed through any implementation of Data Managers. Each interoperability integration will require a compatibility analysis, depending on the use case. ## Reference Implementation -We present an example implementation of Asset Vaults, a deterministic Asset Vault Factory, and a Data Object specialized in managing Asset Vaults. The following implementation assumes the existance of both IDataPointRegistry and IODC implementations. - -The Vault Data Object may hold multiple assets locked under management, which in turn may be exposed through a Data Manager interface implementing a logic equivalent to the fractionalization of the Vault. - - -**Example Vault Interface** +We present an **educational example** implementation showcasing two types of tokens (Fungible and Semi-Fungible) sharing the same storage. The abstraction of the storage from the logic is achieved through the use of **Data Objects**. A factory is used for deploying fungible token contracts that share storage with each semi-fungible NFT representing a collection of fractions. Note that if a `transfer()` is called by either interface (Fungible or Semi-Fungible), both interfaces are emitting an event. -Asset Vaults are an example smart contract designed to implement the minimimalistic approach at asset management. Any user can deploy Asset Vaults through the factory. The role of an Asset Vault smart contract is to manage assets on behalf of the owner. We recommend Asset Vaults be `Ownable2Step` for security reasons. +**This example has not been audited and should not be used in production environments.** -```solidity -pragma solidity ^0.8.0; -interface IVault { - /** - * @notice Executes a state-changing call on a target - * @param target Contract to call - * @param data Data sent to the target, including function selector - * @param value Native coin value sent with the call - * @dev Access to this function SHOULD be protected - */ - function execute(address target, bytes calldata data, uint256 value) external returns (bytes memory); - /** - * @notice Executes a static call (non state-changing) on a target - * @param target Contract to call - * @param data Data sent to the target, including function selector - */ - function executeStatic(address target, bytes calldata data) external view returns (bytes memory); - ... -} -``` - -Vault Factories are example smart contracts that facilitate the deployment of Asset Vaults. - -**Example Vault Factory Interface** -```solidity -pragma solidity ^0.8.0; - -import "IVault.sol"; - -interface IVaultFactory { - function deploy(bytes calldata data) external returns (IVault); - function deployDeterministic(bytes32 salt, bytes calldata data) external returns (IVault); - function computeVaultAddress(address deployer, bytes32 salt, bytes calldata data) external view returns (address); - ... -} -``` - -A Vault Data Object is an implementation of Base Data Object for managing assets through Asset Vaults. As an implementation of IDataObject, this smart contract must implement `read()` and `write()` functions related to handling the data stored on Data Points under management. The logic of `read()` can be implemented with the use of `dispatchRead()` and the `write()` logic with `dispatchWrite()`. In this example, the Vault Data Object also implements some signature verification logic. - -**Example Vault Data Object contract** -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "IVaultFactory.sol"; -import "BaseDataObject.sol"; - -contract VaultDataObject is IERC1271, BaseDataObject { - using EnumerableSet for EnumerableSet.AddressSet; - - bytes4 public constant VAULT_FOR_SALT_SELECTOR = bytes4(keccak256("vaultForSalt(bytes32)")); //vaultForSalt(bytes32) returns(address) - bytes4 public constant ALL_VAULTS_SELECTOR = bytes4(keccak256("allVaults()")); //allVaults() returns(address[] memory) - - bytes4 public constant DEPLOY_VAULT_SELECTOR = bytes4(keccak256("deployVault(address,bytes)")); //deployVault(address factory, bytes calldata data) - bytes4 public constant DEPLOY_DETERMINISTIC_VAULT_SELECTOR = bytes4(keccak256("deployDeterministicVault(address,bytes32,bytes)")); //deployDeterministicVault(address factory, bytes32 salt, bytes calldata data) - bytes4 public constant GRANT_SIGNATURE_VALIDATION_SELECTOR = bytes4(keccak256("grantSignatureValidation(address,bytes32,address)")); //grantSignatureValidation(address vault, bytes32 hash, address signer) - bytes4 public constant REVOKE_SIGNATURE_VALIDATION_SELECTOR = bytes4(keccak256("revokeSignatureValidation(address,bytes32,address)")); //revokeSignatureValidation(address vault, bytes32 hash, address signer) - bytes4 public constant VAULT_EXECUTE_SELECTOR = bytes4(keccak256("vaultExecute(address,address,bytes,uint256)")); //vaultExecute(address vault, address target, bytes calldata data, uint256 value) - bytes4 private constant ERC1271_INVALID_SIGNATURE = 0xffffffff; - - error UnknownVault(); - error UnknownSalt(); - error UnknownDataPoint(); - error DeloyedVaultAlreadyRegistered(); - - event SignatureValidationAdded(address vault, bytes32 hash, address signer); - event SignatureValidationRevoked(address vault, bytes32 hash, address signer); - - struct SignatureVerificationData { - mapping(address vault => mapping(address signer => bool valid)) validSigners; - } - - struct DpData { - EnumerableSet.AddressSet deployedVaults; - mapping(bytes32 salt => address vault) deployedDeterministicVaults; - mapping(bytes32 hash => SignatureVerificationData) validSignatures; - ... - } - - mapping(uint256 dpIdx => DpData) private dpDataStorage; - mapping(address vault => DataPoint) internal vaultsToDataPoints; - - /** - * @inheritdoc IERC1271 - */ - function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue) { - ... - } - - function computeDeterministicVaultAddress(DataPoint dp, address factory, bytes32 salt, bytes calldata data) external view returns (address) { - ... - } - - function datapointOfVault(address vault) public view returns (DataPoint) { - DataPoint dp = vaultsToDataPoints[vault]; - if (DataPoint.unwrap(dp) == bytes32(0)) revert UnknownVault(); - return dp; - } - - function dispatchRead(DataPoint dp, bytes4 operation, bytes calldata data) internal view virtual override returns (bytes memory) { - if (operation == VAULT_FOR_SALT_SELECTOR) { - bytes32 salt = abi.decode(data, (bytes32)); - return abi.encode(_vaultForSalt(dp, salt)); - } else if (operation == ALL_VAULTS_SELECTOR) { - return abi.encode(_allVaults(dp)); - } else { - revert UnknownReadOperation(operation); - } - } - - function dispatchWrite(DataPoint dp, bytes4 operation, bytes calldata data) internal virtual override returns (bytes memory) { - if (operation == DEPLOY_VAULT_SELECTOR) { - (address factory, bytes memory factoryData) = abi.decode(data, (address, bytes)); - return abi.encode(_deployVault(dp, factory, factoryData)); - } else if (operation == DEPLOY_DETERMINISTIC_VAULT_SELECTOR) { - (address factory, bytes32 salt, bytes memory factoryData) = abi.decode(data, (address, bytes32, bytes)); - return abi.encode(_deployDeterministicVault(dp, factory, salt, factoryData)); - } else if (operation == GRANT_SIGNATURE_VALIDATION_SELECTOR) { - (address vault, bytes32 hash, address signer) = abi.decode(data, (address, bytes32, address)); - _grantSignatureValidation(dp, vault, hash, signer); - return ""; - } else if (operation == REVOKE_SIGNATURE_VALIDATION_SELECTOR) { - (address vault, bytes32 hash, address signer) = abi.decode(data, (address, bytes32, address)); - _revokeSignatureValidation(dp, vault, hash, signer); - return ""; - } else if (operation == VAULT_EXECUTE_SELECTOR) { - (address vault, address target, bytes memory vaultCallData, uint256 value) = abi.decode(data, (address, address, bytes, uint256)); - return _vaultExecute(dp, vault, target, vaultCallData, value); - } else { - revert UnknownWriteOperation(operation); - } - } - ... -} -``` - -Finally, we expose a user-facing example Data Manager contract for managing the Data Object. The Data Manager will be implementing `read()` functions for checking the users' `balanceOf()` directly from the Data Object, and `write()` functions through the IODC implementation for the `transfer()` logic. Since multiple Data Managers can make use of the same Data Point, it is possible for several concurrent Data Manager implementations to share a Data Point where they delegate their storage. - - -**Example Fungible Token Data Manager implementation** - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract ERC20DataManager is IERC20, IERC20Metadata, IERC20Errors, Ownable, ERC20Approvals, ERC20Transfers, ERC20Burnable, ERC20Mintable, ERC20Metadata { - bytes4 internal BALANCE_OF_SELECTOR = bytes4(keccak256("balanceOf(address)")); - bytes4 internal TOTAL_SUPPLY_SELECTOR = bytes4(keccak256("totalSupply()")); - bytes4 internal MINT_SELECTOR = bytes4(keccak256("mint(address,uint256)")); - bytes4 internal BURN_SELECTOR = bytes4(keccak256("burn(address,uint256)")); - bytes4 internal TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,address,uint256)")); - - DataPoint internal immutable datapoint; - IDataObject public immutable fungibleDO; - IODC public odc; - mapping(address account => mapping(address spender => uint256)) private _allowances; - - constructor( - bytes32 _datapoint, - address _odc, - address _fungibleDO, - string memory name_, - string memory symbol_ - ) Ownable(msg.sender) ERC20Metadata(name_, symbol_) { - datapoint = DataPoint.wrap(_datapoint); - odc = IODC(_odc); - fungibleDO = IDataObject(_fungibleDO); - } - - function totalSupply() external view override returns (uint256) { - return abi.decode(fungibleDO.read(datapoint, TOTAL_SUPPLY_SELECTOR, ""), (uint256)); - } - - function balanceOf(address account) external view override returns (uint256) { - return abi.decode(fungibleDO.read(datapoint, BALANCE_OF_SELECTOR, abi.encode(account)), (uint256)); - } - - function _checkMinter() internal view override { - _checkOwner(); - } - - function _writeTransfer(address from, address to, uint256 amount) internal override { - if (from == address(0)) { - odc.write(address(fungibleDO), datapoint, MINT_SELECTOR, abi.encode(to, amount)); - } else if (to == address(0)) { - odc.write(address(fungibleDO), datapoint, BURN_SELECTOR, abi.encode(from, amount)); - } else { - odc.write(address(fungibleDO), datapoint, TRANSFER_SELECTOR, abi.encode(from, to, amount)); - } - } -} -``` ## Security Considerations -The access control is separated in three layers: +The access control is separated into three layers: -* **Layer 1**: The Data Point Registry allocates for Data Managers and manages ownerhsip (admin/write rights) of Data Points. -* **Layer 2**: The ODC smart contract implements Access Control by managing Approvals of Data Managers to Data Points. It uses the Data Point Registry to verify who can grant/revoke this access. -* **Layer 3**: The Data Manager exposes functions that can perform `write` operations on the Data Point by calling the ODC implementation. +* **Layer 1**: The Data Point Registry allocates for Data Managers and manages ownership (admin/write rights) of Data Points. +* **Layer 2**: The Data Index smart contract implements Access Control by managing Approvals of Data Managers to Data Points. It uses the Data Point Registry to verify who can grant/revoke this access. +* **Layer 3**: The Data Manager exposes functions that can perform `write` operations on the Data Point by calling the Data Index implementation. -No further security considerations are derived specificly from this ERC. +No further security considerations are derived specifically from this ERC. ## Copyright diff --git a/assets/erc-7208/erc-7208-compat.md b/assets/erc-7208/erc-7208-compat.md index 571ef9f912..8a9a5fe696 100644 --- a/assets/erc-7208/erc-7208-compat.md +++ b/assets/erc-7208/erc-7208-compat.md @@ -1,20 +1,20 @@ -## Appendix: Compatibility Analysis +## Appendix: Interoperability Analysis -We provide a cherrypicked list of possible points of contact between ERC-7208 (on-chain data container) and other tokenization standards and proposals. +We provide a cherrypicked list of possible points of contact between ERC-7208 (on-chain data containers) and other tokenization standards and proposals. -**ERC-1400 (Security Token Standard)**: In aggregate provides a suite of standard interfaces for issuing / redeeming security tokens, managing their ownership and transfer restrictions and providing transparency to token holders on how different subsets of their token balance behave with respect to transfer restrictions, rights and obligations. ERC-7208 can enhance ERC-1400 by offering more dynamic and flexible data management. Data Objects enable the storage and modification of on-chain data related to security tokens, such as compliance information or ownership details. In the case of assets that are already issued under ERC-1400, they can be wrapped into a Vault Data Object and exposed through any Data Manager interface (including ERC-3643 and others). Alternative, if the asset is issued with native Data Point storage, the integration could lead to more efficient and transparent security token offerings. The modular and adaptable nature of ERC-7208 enable transparent enhancements to the internal logic of individual ERC-1400 tokens. +**ERC-1400 (Security Token Standard)**: This ERC provides a suite of standard interfaces for issuing / redeeming security tokens, managing their ownership and transfer restrictions and providing transparency to token holders on how different subsets of their token balance behave with respect to transfer restrictions, rights and obligations. ERC-7208 can enhance ERC-1400 by offering more dynamic and flexible data management architecture. **Data Objects** enable the storage and modification of on-chain data related to security tokens, such as compliance information or ownership details. In the case of assets that are already issued under ERC-1400, they can be wrapped into a **Vault Data Object** and exposed through any **Data Manager** interface (including ERC-3643 and others). Alternative, if the asset is issued with native **Data Point** storage, the integration could lead to more efficient and transparent security token offerings. The modular and adaptable nature of ERC-7208 enable transparent enhancements to the internal logic of individual ERC-1400 tokens. -**EIP-2309 (Consecutive batch minting)**: ERC-7208 is compatible with EIP-2309, allowing for the batch minting process to be enriched with additional data. ODCs could store information related to each batch, such as metadata or batch-specific attributes, without disrupting the minting process. This information may be stored on Data Points, internally within the ODC Implementation, or locally at the Data Manager exposing the EIP-2309 interface. +**EIP-2309 (Consecutive batch minting)**: ERC-7208 is compatible with EIP-2309, allowing for the batch minting process to be enriched with additional data. **Data Objects** could store information related to each batch, such as metadata or batch-specific attributes, without disrupting the minting process. This information may be stored on **Data Points**, and interacted with through a **Data Manager** exposing the EIP-2309 interface. -**EIP-2981 (Royalties)**: ERC-7208 can complement EIP-2981 as a Data Manager by providing a flexible way to handle royalties. Data Objects can store and manage the low level storage of royalty information dynamically and independently from the Data Manager's implemented interface. This enables a complex royalty structure that can change over time or based on certain conditions, like embedding compliance checks on the functions modifying the storage and simultaneously exposing multiple interfaces for accessing the storage. For instance, by leveraging ERC-7208, an individual royalty based NFT can be traded in a compliant manner, concurrently under both an ERC-721 interface as well as an ERC-20 through the use of Data Managers. +**EIP-2981 (Royalties)**: ERC-7208 can complement EIP-2981 as a **Data Manager** by providing a flexible way to handle royalties. **Data Objects** can store and manage the low level storage of royalty information dynamically and independently from the interface used by the end user. This enables a complex royalty structure that can change over time or based on arbitrary conditions, like embedding compliance checks and simultaneously exposing multiple interfaces for accessing the underlying asset. For instance, by leveraging ERC-7208, an individual royalty based NFT can be traded in a compliant manner, concurrently under both an ERC-721 interface as well as an ERC-20 through the use of **Data Managers**. -**ERC-3643 (Security Tokens)**: ERC-3643 defines a *Security Token interface for Regulated Exchanges* based on ERC-20 token standard. The ERC-7208 can be used for wrapping buckets of tokens (irrespective of their ERC) and adapting their logic to the ERC-3643. Additionally, a Data Object storing native ERC-3643 tokens can be used for improving the compliance logic and enabling the trading of underlying securities simultaneously through multiple interfaces that respond to different regulatory frameworks. Moreover, the separation of the storage enables the logic to implement functionalities that were not initially a part of the original ERC, such as identity-based recovery of assets, role-based access control, the introduction of cross-chain support, etc. +**ERC-3643 (Security Tokens)**: ERC-3643 defines a *Security Token interface for Regulated Exchanges* based on ERC-20 token standard. The ERC-7208 can be used for wrapping buckets of tokens (irrespective of their ERC) and adapting their logic to the ERC-3643. Additionally, a **Data Object** storing native ERC-3643 tokens can be used for improving the compliance logic and enabling the trading of underlying securities simultaneously through multiple interfaces that respond to different regulatory frameworks. Moreover, the separation of the storage enables the logic to implement functionalities that were not initially a part of the original ERC, such as identity-based recovery of assets, role-based access control, the introduction of cross-chain support, etc. -**ERC-4337 (Account Abstraction)**: ERC-7208 can provide a standardized method to store and manage the complex data structures required by abstracted accounts. This can include user preferences, access control lists, recovery options, and other customizable account features. The mutable states of abstracted accounts can be efficiently handled using Data Objects. This, in turn, improves the adaptability and security of abstracted accounts. Additionally, an ERC-7208 implementation supporting meta-transactions and Data Points separated by chain-id can be developed to fully abstract account management across blockchains. +**ERC-4337 (Account Abstraction)**: ERC-7208 can provide a standardized method to store and manage the complex data structures required by abstracted accounts. This can include user preferences, access control lists, recovery options, and other customizable account features. The mutable states of abstracted accounts can be efficiently handled using **Data Objects**. This, in turn, improves the adaptability and security of abstracted accounts. Additionally, an ERC-7208 implementation supporting meta-transactions and **Data Points** separated by chain-id can be developed to fully abstract account management across blockchains. -**EIP-4626 (Tokenized Vaults)**: Tokenized Vaults inherit from a single ERC-20 and ERC-2612 for approvals via EIP-712 secp256k1 signatures. ODCs can enhance EIP-4626 by providing a more dynamic data layer for tokenized vaults. Data Objects and ODCs can store information about the assets in the vault, conditions for access, or other relevant data, enabling more nuanced interactions with tokenized vaults. Additionally, the Data Object can store more than a single ERC-20, greatly increasing the capabilities of Tokenized Vaults. +**EIP-4626 (Tokenized Vaults)**: Tokenized Vaults inherit from a single ERC-20 and ERC-2612 for approvals via EIP-712 secp256k1 signatures. ERC-7208 can enhance EIP-4626 by providing a more dynamic data layer for tokenized vaults. **Data Objects** store information about the assets in the vault, conditions for access, or other relevant data, enabling more nuanced interactions with tokenized vaults. Additionally, the **Data Point** can store more than a single ERC-20, greatly increasing the capabilities of Tokenized Vaults. -**ERC-4907 (Shared Ownership)**: The integration of ERC-4907 as a Data Manager with ERC-7208 Data Object storage can enhance the rental experience by allowing for additional rental-related data directly on-chain, such as rental terms, user permissions, and other customizable settings which would be self-contained within Data Points and therefore automatically updated as metadata. ERC-4907's rental mechanism complements ERC-7208's ability to manage mutable on-chain data. By combining these two, NFTs can not only be rented out for specific periods but also have their traits or states dynamically managed and updated during the rental period. This combination enhances security and compliance in NFT transactions, particularly for Real World Asset Tokenization. Rental agreements, regulatory compliance, intelectual property and user rights can be embedded within Data Objects to ensure that the NFT usage adheres to predefined rules. +**ERC-4907 (Shared Ownership)**: The integration of ERC-4907 as a **Data Manager** with ERC-7208 **Data Point** storage can enhance the rental experience by allowing for additional rental-related data directly on-chain, such as rental terms, user permissions, and other customizable settings which would be self-contained within **Data Points** and therefore automatically updated as metadata. ERC-4907's rental mechanism complements ERC-7208's ability to manage mutable on-chain data. By combining these two, NFTs can not only be rented out for specific periods but also have their traits or states dynamically managed and updated during the rental period. This combination enhances security and compliance in NFT transactions, particularly for *Real World Asset Tokenization*. Rental agreements, regulatory compliance, intelectual property and user rights can be embedded within Data Objects to ensure that the NFT usage adheres to predefined rules. -**ERC-7540 (Asynchronous ERC-4626 Tokenized Vaults)**: ERC-7540 vaults's are focused on asynchronous deposit and redemption. Integrating ERC-7540, either by Wrapping into a Data Object or by exposing a 7208 Data Manager, will facilitate more complex financial products. DeFi products like undercollateralized loans, insurance products, or tokenized stocks often require operations to be handled in a non-instantaneous manner. However, the nature of these products requires adhering to regulatory compliance and identity management solutions. This can easily be achieved by implementing the use of on-chain adapters that enhance the logic while keeping the data secure. +**ERC-7540 (Asynchronous ERC-4626 Tokenized Vaults)**: ERC-7540 vaults's are focused on asynchronous deposit and redemption. Integrating ERC-7540, either by Wrapping into a **Data Object** or by exposing an ERC-7208 **Data Manager**, will facilitate more complex financial products. DeFi products like undercollateralized loans, insurance products, or tokenized stocks often require operations to be handled in a non-instantaneous manner. However, the nature of these products requires adhering to regulatory compliance and identity management solutions. This can easily be achieved by implementing the use of on-chain adapters that enhance the logic while keeping the data secure. diff --git a/assets/erc-7208/erc-7208-overview.svg b/assets/erc-7208/erc-7208-overview.svg index 13cc55680e..bd9fa53b8f 100644 --- a/assets/erc-7208/erc-7208-overview.svg +++ b/assets/erc-7208/erc-7208-overview.svg @@ -1,4 +1,4 @@ -
DataObject
DataObject
DataManager
On-chain Data Container
DataManager
DataManager
DataObject
Buckets of assets
and asset data
Access Management
Business Logic and
user interface for
interacting with the data
\ No newline at end of file +
DataObject
DataObject
DataManager
Data Index
 &
Data Point Registry
DataManager
DataManager
DataObject
Asset data Storage
Access Management
Business Logic and
user interface for
interacting with the data
(expose any ERC interface)
\ No newline at end of file diff --git a/assets/erc-7208/erc-7208-technical-overview.svg b/assets/erc-7208/erc-7208-technical-overview.svg index d1ab5cc3cc..cef28c2fa2 100644 --- a/assets/erc-7208/erc-7208-technical-overview.svg +++ b/assets/erc-7208/erc-7208-technical-overview.svg @@ -1,4 +1,4 @@ -
Access Management
ODC_ID => DM_ID => DP_ID
...
...
ODC Smart Contract
ODC ID
Management
DataManager (DM)
Implements business logic
Access DM
Manage ODC
User
Manage DM <=> DataObject relationship
DM Mainteiner
Storage
DataPoint_DM1_1
odc_id1
odc_id2
DataPoint_DM1_2
odc_id1
odc_id2
DataPoint_DM2_1
odc_id1
odc_id2
DataPoint_DM2_2
odc_id1
odc_id2
DataPoint Logic
Performs logic directly related
to storage management
Multiple DataObject (DO)
Contracts
DataObject (DO)
Contract
ODC implementation
(ERC-7208)

DataManager (DM)
Implements business logic
DataManager (DM)
Implements business logic
DataManager (DM)
Implements usecase logic
Data is stored in DataPoints
DataObject exposes low level
Data Management interface
ODC implementation
manages access
and indexes DataObjects
DataPoint Registry

Should provide information if an account can grant access to DP for DMs and DOs

function isAdmin(DataPoint, account) returns (bool)
Verify DP Maintainer
is Admin of DataPoint
Allocate DataPoint
DataManagers Implement
business logic
(user-facing interfaces)
DP Registry implementation
separates the space of
compatible DataPoints
\ No newline at end of file +
Access Management
ID => DM_ID => DP_ID
...
...
DataIndex (DI)
Smart Contract
ID Management
DataManager (DM)
Implements business logic
Access DM
Provides ID
User
Manage DM <=> DataObject relationship
DM Mainteiner
Storage
DataPoint_DM1_1
id_1
id_2
DataPoint_DM1_2
id_1
id_2
DataPoint_DM2_1
id_1
id_2
DataPoint_DM2_2
id_1
id_2
DataPoint Logic
Performs logic directly related
to storage management
Multiple DataObject (DO)
Contracts
DataObject (DO)
Contract
ERC-7208
Technical Overview
DataManager (DM)
Implements business logic
DataManager (DM)
Implements business logic
DataManager (DM)
Implements usecase logic
Data is stored in DataPoints
DataObject exposes low level
Data Management interface
DataIndex implementation
manages access
and indexes DataObjects
DataPoint Registry

Should provide information if an account can grant access to DP for DMs and DOs

function isAdmin(DataPoint, account) returns (bool)
Verify DP Maintainer
is Admin of DataPoint
Allocate DataPoint
DataManagers Implement
business logic
(user-facing interfaces)
DP Registry implementation
separates the space of
compatible DataPoints
\ No newline at end of file From 10f0120c2db3f3374035e85915a472e284ac5421 Mon Sep 17 00:00:00 2001 From: galimba Date: Thu, 1 Aug 2024 20:41:53 +0200 Subject: [PATCH 14/79] Update ERC-7208: pushing example implementation Merged by EIP-Bot. --- assets/erc-7208/contracts/DataIndex.sol | 95 ++++ .../erc-7208/contracts/DataPointRegistry.sol | 78 +++ ...icERC1155WithERC20FractionsDataManager.sol | 452 ++++++++++++++++++ .../MinimalisticERC20FractionDataManager.sol | 157 ++++++ ...alisticERC20FractionDataManagerFactory.sol | 12 + .../MinimalisticFungibleFractionsDO.sol | 380 +++++++++++++++ .../contracts/interfaces/IDataIndex.sol | 49 ++ .../contracts/interfaces/IDataObject.sol | 37 ++ .../interfaces/IDataPointRegistry.sol | 91 ++++ .../IFractionTransferEventEmitter.sol | 20 + .../IFungibleFractionsOperations.sol | 103 ++++ .../contracts/interfaces/IIDManager.sol | 27 ++ .../erc-7208/contracts/utils/ChainidTools.sol | 48 ++ .../erc-7208/contracts/utils/DataPoints.sol | 67 +++ .../contracts/utils/OmnichainAddresses.sol | 77 +++ 15 files changed, 1693 insertions(+) create mode 100644 assets/erc-7208/contracts/DataIndex.sol create mode 100644 assets/erc-7208/contracts/DataPointRegistry.sol create mode 100644 assets/erc-7208/contracts/datamanagers/MinimalisticERC1155WithERC20FractionsDataManager.sol create mode 100644 assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManager.sol create mode 100644 assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManagerFactory.sol create mode 100644 assets/erc-7208/contracts/dataobjects/MinimalisticFungibleFractionsDO.sol create mode 100644 assets/erc-7208/contracts/interfaces/IDataIndex.sol create mode 100644 assets/erc-7208/contracts/interfaces/IDataObject.sol create mode 100644 assets/erc-7208/contracts/interfaces/IDataPointRegistry.sol create mode 100644 assets/erc-7208/contracts/interfaces/IFractionTransferEventEmitter.sol create mode 100644 assets/erc-7208/contracts/interfaces/IFungibleFractionsOperations.sol create mode 100644 assets/erc-7208/contracts/interfaces/IIDManager.sol create mode 100644 assets/erc-7208/contracts/utils/ChainidTools.sol create mode 100644 assets/erc-7208/contracts/utils/DataPoints.sol create mode 100644 assets/erc-7208/contracts/utils/OmnichainAddresses.sol diff --git a/assets/erc-7208/contracts/DataIndex.sol b/assets/erc-7208/contracts/DataIndex.sol new file mode 100644 index 0000000000..f1cb864cbe --- /dev/null +++ b/assets/erc-7208/contracts/DataIndex.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/access/AccessControl.sol"; +import "./interfaces/IDataIndex.sol"; +import "./interfaces/IDataObject.sol"; +import "./interfaces/IIDManager.sol"; +import "./interfaces/IDataPointRegistry.sol"; + +/** + * @title Data Index contract + * @notice Minimalistic implementation of a Data Index contract + */ +contract DataIndex is IDataIndex, IIDManager, AccessControl { + /// @dev Error thrown when the sender is not an admin of the DataPoint + error InvalidDataPointAdmin(DataPoint dp, address sender); + + /// @dev Error thrown when the DataManager is not approved to interact with the DataPoint + error DataManagerNotApproved(DataPoint dp, address dm); + + /// @dev Error thrown when the dataIndex identifier is incorrect + error IncorrectIdentifier(bytes32 diid); + + /** + * @notice Event emitted when DataManager is approved for DataPoint + * @param dp Identifier of the DataPoint + * @param dm Address of DataManager + * @param approved if DataManager is approved + */ + event DataPointDMApprovalChanged(DataPoint dp, address dm, bool approved); + + /// @dev Mapping of DataPoint to DataManagers allowed to write to this DP (in any DataObject) + mapping(DataPoint => mapping(address dm => bool allowed)) dmApprovals; + + /** + * @notice Restricts access to the function, allowing only DataPoint admins + * @param dp DataPoint to check ownership of + */ + modifier onlyDPOwner(DataPoint dp) { + (uint32 chainId, address registry, ) = DataPoints.decode(dp); + ChainidTools.requireCurrentChain(chainId); + bool isAdmin = IDataPointRegistry(registry).isAdmin(dp, msg.sender); + if (!isAdmin) revert InvalidDataPointAdmin(dp, msg.sender); + _; + } + + /** + * @notice Allows access only to DataManagers which was previously approved + * @param dp DataPoint to check DataManager approval for + */ + modifier onlyApprovedDM(DataPoint dp) { + bool approved = dmApprovals[dp][msg.sender]; + if (!approved) revert DataManagerNotApproved(dp, msg.sender); + _; + } + + /// @dev Sets the default admin role + constructor() { + _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); + } + + ///@inheritdoc IDataIndex + function isApprovedDataManager(DataPoint dp, address dm) external view returns (bool) { + return dmApprovals[dp][dm]; + } + + ///@inheritdoc IDataIndex + function allowDataManager(DataPoint dp, address dm, bool approved) external onlyDPOwner(dp) { + dmApprovals[dp][dm] = approved; + emit DataPointDMApprovalChanged(dp, dm, approved); + } + + ///@inheritdoc IDataIndex + function read(address dobj, DataPoint dp, bytes4 operation, bytes calldata data) external view returns (bytes memory) { + return IDataObject(dobj).read(dp, operation, data); + } + + ///@inheritdoc IDataIndex + function write(address dobj, DataPoint dp, bytes4 operation, bytes calldata data) external onlyApprovedDM(dp) returns (bytes memory) { + return IDataObject(dobj).write(dp, operation, data); + } + + ///@inheritdoc IIDManager + function diid(address account, DataPoint) external pure returns (bytes32) { + return bytes32(uint256(uint160(account))); + } + + ///@inheritdoc IIDManager + function ownerOf(bytes32 _diid) external view returns (uint32, address) { + if (_diid & 0xFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000 != 0) revert IncorrectIdentifier(_diid); // Require first 12 bytes empty, leaving only 20 bytes of address non-empty + address account = address(uint160(uint256(_diid))); + if (account == address(0)) revert IncorrectIdentifier(_diid); + return (ChainidTools.chainid(), account); + } +} diff --git a/assets/erc-7208/contracts/DataPointRegistry.sol b/assets/erc-7208/contracts/DataPointRegistry.sol new file mode 100644 index 0000000000..e090083e93 --- /dev/null +++ b/assets/erc-7208/contracts/DataPointRegistry.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {DataPoints, DataPoint} from "./utils/DataPoints.sol"; +import {IDataPointRegistry} from "./interfaces/IDataPointRegistry.sol"; + +/** + * @title DataPointRegistry contract + * @notice Contract for managing the creation, transfer and access control of DataPoints + */ +contract DataPointRegistry is IDataPointRegistry { + /** + * @notice DataPoint access data + * @param owner Owner of the DataPoint + * @param isAdmin Mapping of isAdmin status for each account + */ + struct DPAccessData { + address owner; + mapping(address => bool) isAdmin; + } + + /// @dev Counter for DataPoint allocation + uint256 private counter; + + /// @dev Access data for each DataPoint + mapping(DataPoint => DPAccessData) private accessData; + + /// @inheritdoc IDataPointRegistry + function isAdmin(DataPoint dp, address account) public view returns (bool) { + return accessData[dp].isAdmin[account]; + } + + /// @inheritdoc IDataPointRegistry + function allocate(address owner) external payable returns (DataPoint) { + if (msg.value > 0) revert NativeCoinDepositIsNotAccepted(); + uint256 newCounter = ++counter; + if (newCounter > type(uint32).max) revert CounterOverflow(); + DataPoint dp = DataPoints.encode(address(this), uint32(newCounter)); + DPAccessData storage dpd = accessData[dp]; + dpd.owner = owner; + dpd.isAdmin[owner] = true; + emit DataPointAllocated(dp, owner); + return dp; + } + + /// @inheritdoc IDataPointRegistry + function transferOwnership(DataPoint dp, address newOwner) external { + DPAccessData storage dpd = accessData[dp]; + address currentOwner = dpd.owner; + if (msg.sender != currentOwner) revert InvalidDataPointOwner(dp, msg.sender); + dpd.owner = newOwner; + emit DataPointOwnershipTransferred(dp, currentOwner, newOwner); + } + + /// @inheritdoc IDataPointRegistry + function grantAdminRole(DataPoint dp, address account) external returns (bool) { + DPAccessData storage dpd = accessData[dp]; + if (msg.sender != dpd.owner) revert InvalidDataPointOwner(dp, msg.sender); + if (!isAdmin(dp, account)) { + dpd.isAdmin[account] = true; + emit DataPointAdminGranted(dp, account); + return true; + } + return false; + } + + /// @inheritdoc IDataPointRegistry + function revokeAdminRole(DataPoint dp, address account) external returns (bool) { + DPAccessData storage dpd = accessData[dp]; + if (msg.sender != dpd.owner) revert InvalidDataPointOwner(dp, msg.sender); + if (isAdmin(dp, account)) { + dpd.isAdmin[account] = false; + emit DataPointAdminRevoked(dp, account); + return true; + } + return false; + } +} diff --git a/assets/erc-7208/contracts/datamanagers/MinimalisticERC1155WithERC20FractionsDataManager.sol b/assets/erc-7208/contracts/datamanagers/MinimalisticERC1155WithERC20FractionsDataManager.sol new file mode 100644 index 0000000000..cf8cb6daa7 --- /dev/null +++ b/assets/erc-7208/contracts/datamanagers/MinimalisticERC1155WithERC20FractionsDataManager.sol @@ -0,0 +1,452 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Arrays.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; +import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol"; +import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; +import {IERC1155Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; +import "../interfaces/IDataIndex.sol"; +import "../interfaces/IDataObject.sol"; +import "./MinimalisticERC20FractionDataManagerFactory.sol"; +import "./MinimalisticERC20FractionDataManager.sol"; + +/** + * Deployment process + * 1. Allocate DataPoint via IDataPointRegistry.allocate() + * 2. Deploy ERC1155WithERC20FractionsDataManager (or an extending contract) + * 3. Grant Admin role on the DataPoint to the deployed contract + */ +contract MinimalisticERC1155WithERC20FractionsDataManager is IFractionTransferEventEmitter, IERC1155, IERC1155Errors, ERC165, Ownable { + using Arrays for uint256[]; + + error IncorrectId(uint256 id); + event ERC20FractionDataManagerDeployed(uint256 id, address dm); + + string private _name; + string private _symbol; + string private _defaultURI = ""; + DataPoint internal immutable datapoint; + IDataObject public immutable fungibleFractionsDO; + IDataIndex public dataIndex; + mapping(address account => mapping(address operator => bool)) private _operatorApprovals; + mapping(uint256 id => address erc20dm) public fractionManagersById; + mapping(address erc20dm => uint256 id) public fractionManagersByAddress; + MinimalisticERC20FractionDataManagerFactory erc20FractionsDMFactory; + + modifier onlyMinter() { + _checkMinter(); + _; + } + + constructor( + bytes32 _dp, + address _dataIndex, + address _fungibleFractionsDO, + address _erc20FractionsDMFactory, + string memory name_, + string memory symbol_ + ) Ownable(msg.sender) { + _name = name_; + _symbol = symbol_; + datapoint = DataPoint.wrap(_dp); + dataIndex = IDataIndex(_dataIndex); + fungibleFractionsDO = IDataObject(_fungibleFractionsDO); + erc20FractionsDMFactory = MinimalisticERC20FractionDataManagerFactory(_erc20FractionsDMFactory); + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { + return interfaceId == type(IERC1155).interfaceId || interfaceId == type(IERC1155MetadataURI).interfaceId || super.supportsInterface(interfaceId); + } + + function setDefaultURI(string calldata defaultURI) external onlyOwner { + _setDefaultURI(defaultURI); + } + + function totalSupply() public view returns (uint256) { + return abi.decode(fungibleFractionsDO.read(datapoint, IFungibleFractionsOperations.totalSupplyAll.selector, ""), (uint256)); + } + + function totalSupply(uint256 id) public view returns (uint256) { + return abi.decode(fungibleFractionsDO.read(datapoint, IFungibleFractionsOperations.totalSupply.selector, abi.encode(id)), (uint256)); + } + + function balanceOf(address account, uint256 id) public view returns (uint256) { + return abi.decode(fungibleFractionsDO.read(datapoint, IFungibleFractionsOperations.balanceOf.selector, abi.encode(account, id)), (uint256)); + } + + function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view returns (uint256[] memory) { + return + abi.decode( + fungibleFractionsDO.read(datapoint, IFungibleFractionsOperations.balanceOfBatchAccounts.selector, abi.encode(accounts, ids)), + (uint256[]) + ); + } + + function uri(uint256) public view virtual returns (string memory) { + return _defaultURI; + } + + function name() public view returns (string memory) { + return _name; + } + function symbol() public view returns (string memory) { + return _symbol; + } + + /** + * @dev See {IERC1155-setApprovalForAll}. + */ + function setApprovalForAll(address operator, bool approved) public virtual { + _setApprovalForAll(_msgSender(), operator, approved); + } + + /** + * @dev See {IERC1155-isApprovedForAll}. + */ + function isApprovedForAll(address account, address operator) public view virtual returns (bool) { + return _operatorApprovals[account][operator]; + } + + /** + * @dev Approve `operator` to operate on all of `owner` tokens + * + * Emits an {ApprovalForAll} event. + * + * Requirements: + * + * - `operator` cannot be the zero address. + */ + function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { + if (operator == address(0)) { + revert ERC1155InvalidOperator(address(0)); + } + _operatorApprovals[owner][operator] = approved; + emit ApprovalForAll(owner, operator, approved); + } + + /** + * @dev See {IERC1155-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) public virtual { + address sender = _msgSender(); + if (from != sender && !isApprovedForAll(from, sender)) { + revert ERC1155MissingApprovalForAll(sender, from); + } + _safeTransferFrom(from, to, id, value, data); + } + + /** + * @dev See {IERC1155-safeBatchTransferFrom}. + */ + function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external virtual { + address sender = _msgSender(); + if (from != sender && !isApprovedForAll(from, sender)) { + revert ERC1155MissingApprovalForAll(sender, from); + } + _safeBatchTransferFrom(from, to, ids, values, data); + } + + /** + * @dev Transfers a `value` tokens of token type `id` from `from` to `to`. + * + * Emits a {TransferSingle} event. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - `from` must have a balance of tokens of type `id` of at least `value` amount. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the + * acceptance magic value. + */ + function _safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) internal { + if (to == address(0)) { + revert ERC1155InvalidReceiver(address(0)); + } + if (from == address(0)) { + revert ERC1155InvalidSender(address(0)); + } + _updateWithAcceptanceCheck(from, to, id, value, data); + } + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. + * + * Emits a {TransferBatch} event. + * + * Requirements: + * + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the + * acceptance magic value. + * - `ids` and `values` must have the same length. + */ + function _safeBatchTransferFrom(address from, address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal { + if (ids.length != values.length) { + revert ERC1155InvalidArrayLength(ids.length, values.length); + // DO NOT remove this check without refactoring ERC1155WithERC20FractionsDataManager._update() which relies on it! + } + + if (to == address(0)) { + revert ERC1155InvalidReceiver(address(0)); + } + if (from == address(0)) { + revert ERC1155InvalidSender(address(0)); + } + if (ids.length == 1 && values.length == 1) { + uint256 id = ids.unsafeMemoryAccess(0); + uint256 value = values.unsafeMemoryAccess(0); + _updateWithAcceptanceCheck(from, to, id, value, data); + } else { + _updateWithAcceptanceCheck(from, to, ids, values, data); + } + } + + /** + * @dev Version of {_update} that performs the token acceptance check by calling + * {IERC1155Receiver-onERC1155Received} or {IERC1155Receiver-onERC1155BatchReceived} on the receiver address if it + * contains code (eg. is a smart contract at the moment of execution). + * + * IMPORTANT: Overriding this function is discouraged because it poses a reentrancy risk from the receiver. So any + * update to the contract state after this function would break the check-effect-interaction pattern. Consider + * overriding {_update} instead. + */ + function _updateWithAcceptanceCheck(address from, address to, uint256 id, uint256 value, bytes memory data) internal virtual { + _update(from, to, id, value); + if (to != address(0)) { + address operator = _msgSender(); + _doSafeTransferAcceptanceCheck(operator, from, to, id, value, data); + } + } + + /** + * @dev Version of {_update} that performs the token acceptance check by calling + * {IERC1155Receiver-onERC1155Received} or {IERC1155Receiver-onERC1155BatchReceived} on the receiver address if it + * contains code (eg. is a smart contract at the moment of execution). + * + * IMPORTANT: Overriding this function is discouraged because it poses a reentrancy risk from the receiver. So any + * update to the contract state after this function would break the check-effect-interaction pattern. Consider + * overriding {_update} instead. + */ + function _updateWithAcceptanceCheck(address from, address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal virtual { + _update(from, to, ids, values); + if (to != address(0)) { + address operator = _msgSender(); + _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, values, data); + } + } + + /** + * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. Will mint (or burn) if `from` + * (or `to`) is the zero address. + * + * Emits a {TransferSingle} event if the arrays contain one element, and {TransferBatch} otherwise. + * + * Requirements: + * + * - If `to` refers to a smart contract, it must implement either {IERC1155Receiver-onERC1155Received} + * or {IERC1155Receiver-onERC1155BatchReceived} and return the acceptance magic value. + * - `ids` and `values` must have the same length. + * + * NOTE: The ERC-1155 acceptance check is not performed in this function. See {_updateWithAcceptanceCheck} instead. + */ + function _updateInternal(address from, address to, uint256 id, uint256 value) internal virtual { + address operator = _msgSender(); + + _writeTransfer(from, to, id, value); + + emit TransferSingle(operator, from, to, id, value); + } + + /** + * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. Will mint (or burn) if `from` + * (or `to`) is the zero address. + * + * Emits a {TransferSingle} event if the arrays contain one element, and {TransferBatch} otherwise. + * + * Requirements: + * + * - If `to` refers to a smart contract, it must implement either {IERC1155Receiver-onERC1155Received} + * or {IERC1155Receiver-onERC1155BatchReceived} and return the acceptance magic value. + * - `ids` and `values` must have the same length. + * + * NOTE: The ERC-1155 acceptance check is not performed in this function. See {_updateWithAcceptanceCheck} instead. + * NOTE: Array length check is not performed in this function and must be performed in the caller + */ + function _updateInternal(address from, address to, uint256[] memory ids, uint256[] memory values) internal virtual { + address operator = _msgSender(); + + _writeTransferBatch(from, to, ids, values); + emit TransferBatch(operator, from, to, ids, values); + } + + /** + * @dev Performs an acceptance check by calling {IERC1155-onERC1155Received} on the `to` address + * if it contains code at the moment of execution. + */ + function _doSafeTransferAcceptanceCheck(address operator, address from, address to, uint256 id, uint256 value, bytes memory data) private { + if (to.code.length > 0) { + try IERC1155Receiver(to).onERC1155Received(operator, from, id, value, data) returns (bytes4 response) { + if (response != IERC1155Receiver.onERC1155Received.selector) { + // Tokens rejected + revert ERC1155InvalidReceiver(to); + } + } catch (bytes memory reason) { + if (reason.length == 0) { + // non-ERC1155Receiver implementer + revert ERC1155InvalidReceiver(to); + } else { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, reason), mload(reason)) + } + } + } + } + } + + /** + * @dev Performs a batch acceptance check by calling {IERC1155-onERC1155BatchReceived} on the `to` address + * if it contains code at the moment of execution. + */ + function _doSafeBatchTransferAcceptanceCheck( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory values, + bytes memory data + ) private { + if (to.code.length > 0) { + try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, values, data) returns (bytes4 response) { + if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { + // Tokens rejected + revert ERC1155InvalidReceiver(to); + } + } catch (bytes memory reason) { + if (reason.length == 0) { + // non-ERC1155Receiver implementer + revert ERC1155InvalidReceiver(to); + } else { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, reason), mload(reason)) + } + } + } + } + } + + function _setDefaultURI(string memory defaultURI) internal virtual { + _defaultURI = defaultURI; + } + + function _checkMinter() internal view { + _checkOwner(); + } + + function _writeTransfer(address from, address to, uint256 id, uint256 value) internal virtual { + if (from == address(0)) { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.mint.selector, abi.encode(to, id, value)); + } else if (to == address(0)) { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.burn.selector, abi.encode(from, id, value)); + } else { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.transferFrom.selector, abi.encode(from, to, id, value)); + } + } + + function _writeTransferBatch(address from, address to, uint256[] memory ids, uint256[] memory values) internal virtual { + if (from == address(0)) { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.batchMint.selector, abi.encode(to, ids, values)); + } else if (to == address(0)) { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.batchBurn.selector, abi.encode(from, ids, values)); + } else { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.batchTransferFrom.selector, abi.encode(from, to, ids, values)); + } + } + + function mint(address to, uint256 id, uint256 value, bytes memory data) public virtual onlyMinter { + _mint(to, id, value, data); + } + + function batchMint(address, uint256[] memory, uint256[] memory, bytes memory) public pure { + revert("Batch mint not supported"); // it will be very expensive anyway + } + + function fractionTransferredNotify(address from, address to, uint256 value) external { + uint256 id = fractionManagersByAddress[_msgSender()]; + if (id == 0) revert WrongTransferNotificationSource(); + emit TransferSingle(_msgSender(), from, to, id, value); + } + + function _mint(address to, uint256 id, uint256 value, bytes memory data) internal virtual { + if (id == 0) revert IncorrectId(id); + _deployERC20DMIfNotDeployed(id, data); + _updateWithAcceptanceCheck(address(0), to, id, value, data); + } + + function _update(address from, address to, uint256 id, uint256 value) internal { + _updateInternal(from, to, id, value); + _erc20TransferNotify(id, from, to, value); + } + + function _update(address from, address to, uint256[] memory ids, uint256[] memory values) internal { + _updateInternal(from, to, ids, values); + for (uint256 i; i < ids.length; i++) { + uint256 id = ids.unsafeMemoryAccess(i); + uint256 value = ids.unsafeMemoryAccess(i); // We have an array length check in ERC1155Transfers._safeBatchTransferFrom() + _erc20TransferNotify(id, from, to, value); + } + } + + function _deployERC20DMIfNotDeployed(uint256 id, bytes memory data) internal { + if (fractionManagersById[id] != address(0)) return; // Already deployed + (string memory name_, string memory symbol_) = _prepareNameAndSymbol(data, id); + _deployERC20DM(id, name_, symbol_); + } + + function _afterDeployERC20DM(address deployedDM) internal virtual {} + + function _prepareNameAndSymbol(bytes memory data, uint256 id) private view returns (string memory, string memory) { + string memory name_; + string memory symbol_; + if (data.length != 0) { + (name_, symbol_) = abi.decode(data, (string, string)); + } else { + name_ = string.concat(name(), " ", Strings.toString(id)); + symbol_ = string.concat(symbol(), "-", Strings.toString(id)); + } + return (name_, symbol_); + } + + function _deployERC20DM(uint256 id, string memory name_, string memory symbol_) private { + address erc20dm = erc20FractionsDMFactory.deploy(id); + MinimalisticERC20FractionDataManager(erc20dm).initialize( + DataPoint.unwrap(datapoint), + address(dataIndex), + address(fungibleFractionsDO), + address(this), + id, + name_, + symbol_ + ); + + fractionManagersById[id] = erc20dm; + fractionManagersByAddress[erc20dm] = id; + + dataIndex.allowDataManager(datapoint, erc20dm, true); + + _afterDeployERC20DM(erc20dm); + + emit ERC20FractionDataManagerDeployed(id, erc20dm); + } + + function _erc20TransferNotify(uint256 id, address from, address to, uint256 value) private { + IFractionTransferEventEmitter(fractionManagersById[id]).fractionTransferredNotify(from, to, value); + } +} diff --git a/assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManager.sol b/assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManager.sol new file mode 100644 index 0000000000..93aa92d016 --- /dev/null +++ b/assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManager.sol @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "../interfaces/IDataIndex.sol"; +import "../interfaces/IDataObject.sol"; +import "../interfaces/IFungibleFractionsOperations.sol"; +import "../interfaces/IFractionTransferEventEmitter.sol"; + +contract MinimalisticERC20FractionDataManager is IFractionTransferEventEmitter, IERC20, IERC20Errors, OwnableUpgradeable { + uint8 private constant DECIMALS = 0; + + DataPoint internal datapoint; + IDataObject public fungibleFractionsDO; + IDataIndex public dataIndex; + address public erc1155dm; + uint256 public erc1155ID; + + string private _name; + string private _symbol; + + mapping(address account => mapping(address spender => uint256)) private _allowances; + + modifier onlyTransferNotifier() { + if (_msgSender() != erc1155dm) revert WrongTransferNotificationSource(); + _; + } + + function initialize( + bytes32 _datapoint, + address _dataIndex, + address _fungibleFractionsDO, + address _erc1155dm, + uint256 _erc1155ID, + string memory name_, + string memory symbol_ + ) external initializer { + __Ownable_init_unchained(_msgSender()); + __MinimalisticERC20FractionDataManager_init_unchained(_datapoint, _dataIndex, _fungibleFractionsDO, _erc1155dm, _erc1155ID, name_, symbol_); + } + + function __MinimalisticERC20FractionDataManager_init_unchained( + bytes32 _datapoint, + address _dataIndex, + address _fungibleFractionsDO, + address _erc1155dm, + uint256 _erc1155ID, + string memory name_, + string memory symbol_ + ) internal onlyInitializing { + datapoint = DataPoint.wrap(_datapoint); + dataIndex = IDataIndex(_dataIndex); + fungibleFractionsDO = IDataObject(_fungibleFractionsDO); + erc1155dm = _erc1155dm; + erc1155ID = _erc1155ID; + _name = name_; + _symbol = symbol_; + } + + function decimals() external pure returns (uint8) { + return DECIMALS; + } + + function name() external view returns (string memory) { + return _name; + } + + function symbol() external view returns (string memory) { + return _symbol; + } + + function totalSupply() external view override returns (uint256) { + return abi.decode(fungibleFractionsDO.read(datapoint, IFungibleFractionsOperations.totalSupply.selector, abi.encode(erc1155ID)), (uint256)); + } + + function balanceOf(address account) external view override returns (uint256) { + return abi.decode(fungibleFractionsDO.read(datapoint, IFungibleFractionsOperations.balanceOf.selector, abi.encode(account, erc1155ID)), (uint256)); + } + + function fractionTransferredNotify(address from, address to, uint256 amount) external onlyTransferNotifier { + emit Transfer(from, to, amount); + } + + function allowance(address owner, address spender) public view returns (uint256) { + return _allowances[owner][spender]; + } + + function approve(address spender, uint256 value) public returns (bool) { + if (_msgSender() == address(0)) { + revert ERC20InvalidApprover(address(0)); + } + if (spender == address(0)) { + revert ERC20InvalidSpender(address(0)); + } + _allowances[_msgSender()][spender] = value; + emit Approval(_msgSender(), spender, value); + return true; + } + + function transfer(address to, uint256 amount) external virtual override returns (bool) { + if (to == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _beforeTokenTransfer(_msgSender(), to, amount); + + _writeTransfer(_msgSender(), to, amount); + + emit Transfer(_msgSender(), to, amount); + return true; + } + + function transferFrom(address from, address to, uint256 amount) external virtual override returns (bool) { + _spendAllowance(from, _msgSender(), amount); + _beforeTokenTransfer(from, to, amount); + + if (from == address(0)) { + revert ERC20InvalidSender(address(0)); + } + if (to == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + + _writeTransfer(from, to, amount); + + emit Transfer(from, to, amount); + return true; + } + + function _spendAllowance(address owner, address spender, uint256 amount) internal { + uint256 currentAllowance = _allowances[owner][spender]; + if (currentAllowance != type(uint256).max) { + if (currentAllowance < amount) { + revert ERC20InsufficientAllowance(spender, currentAllowance, amount); + } + unchecked { + _allowances[owner][spender] = currentAllowance - amount; + } + } + } + + function _writeTransfer(address from, address to, uint256 amount) internal { + if (from == address(0)) { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.mint.selector, abi.encode(to, erc1155ID, amount)); + } else if (to == address(0)) { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.burn.selector, abi.encode(from, erc1155ID, amount)); + } else { + dataIndex.write(address(fungibleFractionsDO), datapoint, IFungibleFractionsOperations.transferFrom.selector, abi.encode(from, to, erc1155ID, amount)); + } + IFractionTransferEventEmitter(erc1155dm).fractionTransferredNotify(from, to, amount); + } + + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} +} diff --git a/assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManagerFactory.sol b/assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManagerFactory.sol new file mode 100644 index 0000000000..b030746d24 --- /dev/null +++ b/assets/erc-7208/contracts/datamanagers/MinimalisticERC20FractionDataManagerFactory.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/utils/Create2.sol"; +import "./MinimalisticERC20FractionDataManager.sol"; + +contract MinimalisticERC20FractionDataManagerFactory { + function deploy(uint256 id) external returns (address) { + bytes32 salt = keccak256(abi.encodePacked(msg.sender, id)); + return Create2.deploy(0, salt, type(MinimalisticERC20FractionDataManager).creationCode); + } +} diff --git a/assets/erc-7208/contracts/dataobjects/MinimalisticFungibleFractionsDO.sol b/assets/erc-7208/contracts/dataobjects/MinimalisticFungibleFractionsDO.sol new file mode 100644 index 0000000000..a15ccf6b04 --- /dev/null +++ b/assets/erc-7208/contracts/dataobjects/MinimalisticFungibleFractionsDO.sol @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "@openzeppelin/contracts/utils/Arrays.sol"; +import "../interfaces/IIDManager.sol"; +import "../interfaces/IFungibleFractionsOperations.sol"; +import "../interfaces/IDataPointRegistry.sol"; +import "../interfaces/IDataIndex.sol"; +import "../interfaces/IDataObject.sol"; +import "../utils/OmnichainAddresses.sol"; + +/** + * @title Minimalistic Fungible Fractions Data Object + * @notice DataObject with base funtionality of Fungible Fractions (Can be used for ERC1155-Compatible DataManagers) + * @dev This contract exposes base functionality of Fungible Fraction tokens, including + * balanceOf, totalSupply, exists, transferFrom, mint, burn and their batch variants. + * + * NOTE: This contract is expected to be used by a DataManager contract, which could + * implement a fungible token interface and provide more advanced features like approvals, + * access control, metadata management, etc. As may be an ERC1155 token. + * + * This contract only emit basic events, it is expected that the DataManager contract will + * emit the events for the token operations + */ +contract MinimalisticFungibleFractionsDO is IDataObject { + using Arrays for uint256[]; + using Arrays for address[]; + using EnumerableSet for EnumerableSet.UintSet; + + /** + * @notice Error thrown when the msg.sender is not the expected caller + * @param dp The DataPoint identifier + * @param sender The msg.sender address + */ + error InvalidCaller(DataPoint dp, address sender); + + /** + * @notice Error thrown when the DataPoint is not initialized with a DataIndex implementation + * @param dp The DataPoint identifier + */ + error UninitializedDataPoint(DataPoint dp); + + /// @dev Error thrown when the operation arguments are wrong + error WrongOperationArguments(); + + /** + * @notice Error thrown when the read operation is unknown + * @param selector The operation selector + */ + error UnknownReadOperation(bytes4 selector); + + /** + * @notice Error thrown when the write operation is unknown + * @param selector The operation selector + */ + error UnknownWriteOperation(bytes4 selector); + + /** + * @notice Error thrown when the balance is insufficient + * @param diid The DataIndex identifier + * @param id The id of the token + * @param balance The current balance + * @param value The requested amount + */ + error InsufficientBalance(bytes32 diid, uint256 id, uint256 balance, uint256 value); + + /** + * @notice Error thrown when the total supply is insufficient + * @param id The id of the token + * @param totalSupply The current total supply + * @param value The requested amount + * @dev This should never happen because we've already checked "from" balance + */ + error InsufficientTotalSupply(uint256 id, uint256 totalSupply, uint256 value); + + /// @dev Error thrown when the params length mismatch + error ArrayLengthMismatch(); + + /** + * @notice Event emitted when the DataIndex implementation is set + * @param dp The DataPoint identifier + * @param dataIndexImplementation The DataIndex implementation address + */ + event DataIndexImplementationSet(DataPoint dp, address dataIndexImplementation); + + /** + * @notice Data structure for storing Fungible Fractions data + * @param totalSupplyAll Total supply of all tokens + * @param totalSupply Mapping of token id to total supply + * @dev Data related to the DataPoint as a whole + */ + struct DpData { + uint256 totalSupplyAll; + mapping(uint256 id => uint256 totalSupplyOfId) totalSupply; + } + + /** + * @notice Data structure for storing Fungible Fractions data of a user + * @param ids Enumerable set of object (ERC1155 token) ids + * @param balances Mapping of object (ERC1155 token) id to balance of the user owning diid + * @dev Data related to a specific user of a DataPoint (user identified by his DataIndex id) + */ + struct DiidData { + EnumerableSet.UintSet ids; + mapping(uint256 id => uint256 value) balances; + } + + /** + * @notice Data structure to store DataPoint data + * @param dataIndexImplementation The DataIndex implementation set for the DataPoint + * @param dpData The DataPoint data + * @param dataIndexData Mapping of diid to user data + */ + struct DataPointStorage { + IDataIndex dataIndexImplementation; + DpData dpData; + mapping(bytes32 diid => DiidData) diidData; + } + + /// @dev Mapping of DataPoint to DataPointStorage + mapping(DataPoint => DataPointStorage) private dpStorages; + + /** + * @notice Modifier to check if the caller is the DataIndex implementation set for the DataPoint + * @param dp The DataPoint identifier + */ + modifier onlyDataIndex(DataPoint dp) { + DataPointStorage storage dps = _dataPointStorage(dp); + if (address(dps.dataIndexImplementation) != msg.sender) revert InvalidCaller(dp, msg.sender); + _; + } + + /// @inheritdoc IDataObject + function setDIImplementation(DataPoint dp, IDataIndex newImpl) external { + DataPointStorage storage dps = dpStorages[dp]; + if (address(dps.dataIndexImplementation) == address(0)) { + // Registering new DataPoint + // Should be called by DataPoint Admin + if (!_isDataPointAdmin(dp, msg.sender)) revert InvalidCaller(dp, msg.sender); + } else { + // Updating the DataPoint + // Should be called by current DataIndex or DataPoint Admin + if ((address(dps.dataIndexImplementation) != msg.sender) && !_isDataPointAdmin(dp, msg.sender)) revert InvalidCaller(dp, msg.sender); + } + dps.dataIndexImplementation = newImpl; + emit DataIndexImplementationSet(dp, address(newImpl)); + } + + // =========== Dispatch functions ============ + /// @inheritdoc IDataObject + function read(DataPoint dp, bytes4 operation, bytes calldata data) external view returns (bytes memory) { + return _dispatchRead(dp, operation, data); + } + + /// @inheritdoc IDataObject + function write(DataPoint dp, bytes4 operation, bytes calldata data) external onlyDataIndex(dp) returns (bytes memory) { + return _dispatchWrite(dp, operation, data); + } + + function _dispatchRead(DataPoint dp, bytes4 operation, bytes calldata data) internal view virtual returns (bytes memory) { + if (operation == IFungibleFractionsOperations.balanceOf.selector) { + (address account, uint256 id) = abi.decode(data, (address, uint256)); + return abi.encode(_balanceOf(dp, account, id)); + } else if (operation == IFungibleFractionsOperations.balanceOfBatchAccounts.selector) { + (address[] memory accounts, uint256[] memory ids) = abi.decode(data, (address[], uint256[])); + return abi.encode(_balanceOfBatchAccounts(dp, accounts, ids)); + } else if (operation == IFungibleFractionsOperations.totalSupply.selector) { + return abi.encode(_totalSupply(dp, abi.decode(data, (uint256)))); + } else if (operation == IFungibleFractionsOperations.totalSupplyAll.selector) { + if (data.length != 0) revert WrongOperationArguments(); + return abi.encode(_totalSupplyAll(dp)); + } else if (operation == IFungibleFractionsOperations.exists.selector) { + return abi.encode(_exists(dp, abi.decode(data, (uint256)))); + } else { + revert UnknownReadOperation(operation); + } + } + + function _dispatchWrite(DataPoint dp, bytes4 operation, bytes calldata data) internal virtual returns (bytes memory) { + if (operation == IFungibleFractionsOperations.transferFrom.selector) { + (address from, address to, uint256 id, uint256 value) = abi.decode(data, (address, address, uint256, uint256)); + _transferFrom(dp, from, to, id, value); + return ""; + } else if (operation == IFungibleFractionsOperations.mint.selector) { + (address to, uint256 id, uint256 value) = abi.decode(data, (address, uint256, uint256)); + _mint(dp, to, id, value); + return ""; + } else if (operation == IFungibleFractionsOperations.burn.selector) { + (address from, uint256 id, uint256 value) = abi.decode(data, (address, uint256, uint256)); + _burn(dp, from, id, value); + return ""; + } else if (operation == IFungibleFractionsOperations.batchTransferFrom.selector) { + (address from, address to, uint256[] memory ids, uint256[] memory values) = abi.decode(data, (address, address, uint256[], uint256[])); + _batchTransferFrom(dp, from, to, ids, values); + return ""; + } else { + revert UnknownWriteOperation(operation); + } + } + + // =========== Logic implementation ============ + + function _balanceOf(DataPoint dp, address account, uint256 id) internal view returns (uint256) { + bytes32 diid = _tryDiid(dp, account); + if (diid == 0) return 0; + (bool success, DiidData storage od) = _tryDiidData(dp, diid); + return success ? od.balances[id] : 0; + } + + function _balanceOfBatchAccounts(DataPoint dp, address[] memory accounts, uint256[] memory ids) internal view returns (uint256[] memory balances) { + if (accounts.length != ids.length) revert ArrayLengthMismatch(); + balances = new uint256[](accounts.length); + for (uint256 i; i < accounts.length; i++) { + uint256 id = ids.unsafeMemoryAccess(i); + address account = accounts.unsafeMemoryAccess(i); + bytes32 diid = _tryDiid(dp, account); + if (diid == 0) { + balances[i] = 0; + } else { + (bool success, DiidData storage od) = _tryDiidData(dp, diid); + balances[i] = success ? od.balances[id] : 0; + } + } + } + + function _totalSupply(DataPoint dp, uint256 id) internal view returns (uint256) { + (bool success, DpData storage dd) = _tryDpData(dp); + return success ? dd.totalSupply[id] : 0; + } + + function _totalSupplyAll(DataPoint dp) internal view returns (uint256) { + (bool success, DpData storage dd) = _tryDpData(dp); + return success ? dd.totalSupplyAll : 0; + } + + function _exists(DataPoint dp, uint256 id) internal view returns (bool) { + (bool success, DpData storage dd) = _tryDpData(dp); + return success ? (dd.totalSupply[id] > 0) : false; + } + + function _transferFrom(DataPoint dp, address from, address to, uint256 id, uint256 value) internal virtual { + bytes32 diidFrom = _diid(dp, from); + bytes32 diidTo = _diid(dp, to); + DiidData storage diiddFrom = _diidData(dp, diidFrom); + DiidData storage diiddTo = _diidData(dp, diidTo); + _decreaseBalance(diiddFrom, id, value, dp, diidFrom); + _increaseBalance(diiddTo, id, value, dp, diidTo); + } + + function _mint(DataPoint dp, address to, uint256 id, uint256 value) internal virtual { + bytes32 diidTo = _diid(dp, to); + DiidData storage diiddTo = _diidData(dp, diidTo); + _increaseBalance(diiddTo, id, value, dp, diidTo); + + DpData storage dpd = _dpData(dp); + dpd.totalSupply[id] += value; + dpd.totalSupplyAll += value; + } + + function _burn(DataPoint dp, address from, uint256 id, uint256 value) internal virtual { + bytes32 diidFrom = _diid(dp, from); + DiidData storage diiddFrom = _diidData(dp, diidFrom); + _decreaseBalance(diiddFrom, id, value, dp, diidFrom); + DpData storage dpd = _dpData(dp); + uint256 totalSupply = dpd.totalSupply[id]; + if (totalSupply < value) revert InsufficientTotalSupply(id, totalSupply, value); + unchecked { + totalSupply -= value; + } + dpd.totalSupply[id] = totalSupply; + uint256 totalSupplyAll = dpd.totalSupplyAll; + if (totalSupplyAll < value) revert InsufficientTotalSupply(id, totalSupplyAll, value); + unchecked { + totalSupplyAll -= value; + } + dpd.totalSupplyAll = totalSupplyAll; + } + + function _batchTransferFrom(DataPoint dp, address from, address to, uint256[] memory ids, uint256[] memory values) internal virtual { + if (ids.length != values.length) revert ArrayLengthMismatch(); + bytes32 diidFrom = _diid(dp, from); + bytes32 diidTo = _diid(dp, to); + DiidData storage diiddFrom = _diidData(dp, diidFrom); + DiidData storage diiddTo = _diidData(dp, diidTo); + for (uint256 i; i < ids.length; i++) { + uint256 id = ids.unsafeMemoryAccess(i); + uint256 value = values.unsafeMemoryAccess(i); + _decreaseBalance(diiddFrom, id, value, dp, diidFrom); + _increaseBalance(diiddTo, id, value, dp, diidTo); + } + } + + function _increaseBalance(DiidData storage diidd, uint256 id, uint256 value, DataPoint, bytes32) private { + diidd.balances[id] += value; + diidd.ids.add(id); // if id is already in the set, this call will return false, but we don't care + } + + function _decreaseBalance(DiidData storage diidd, uint256 id, uint256 value, DataPoint, bytes32 diidFrom) private { + uint256 diidBalance = diidd.balances[id]; + if (diidBalance < value) { + revert InsufficientBalance(diidFrom, id, diidBalance, value); + } else { + unchecked { + diidBalance -= value; + } + diidd.balances[id] = diidBalance; + if (diidBalance == 0) { + diidd.ids.remove(id); + } + } + } + + // =========== Helper functions ============ + + function _isDataPointAdmin(DataPoint dp, address account) internal view returns (bool) { + (uint32 chainId, address registry, ) = DataPoints.decode(dp); + ChainidTools.requireCurrentChain(chainId); + return IDataPointRegistry(registry).isAdmin(dp, account); + } + + function _diid(DataPoint dp, address account) internal view returns (bytes32) { + return IIDManager(msg.sender).diid(account, dp); + } + + function _tryDiid(DataPoint dp, address account) internal view returns (bytes32) { + try IIDManager(msg.sender).diid(account, dp) returns (bytes32 diid) { + return diid; + } catch { + return 0; + } + } + + function _dpData(DataPoint dp) internal view returns (DpData storage) { + DataPointStorage storage dps = _dataPointStorage(dp); + return dps.dpData; + } + + function _diidData(DataPoint dp, bytes32 diid) internal view returns (DiidData storage) { + DataPointStorage storage dps = _dataPointStorage(dp); + return dps.diidData[diid]; + } + + function _tryDpData(DataPoint dp) internal view returns (bool success, DpData storage) { + (bool found, DataPointStorage storage dps) = _tryDataPointStorage(dp); + if (!found) { + return (false, dps.dpData); + } + return (true, dps.dpData); + } + + function _tryDiidData(DataPoint dp, bytes32 diid) internal view returns (bool success, DiidData storage) { + (bool found, DataPointStorage storage dps) = _tryDataPointStorage(dp); + if (!found) { + return (false, dps.diidData[bytes32(0)]); + } + DiidData storage diidd = dps.diidData[diid]; + if (diidd.ids.length() == 0) { + // Here we use length of ids array as a flag that there is no data for the diid + return (false, diidd); + } + return (true, diidd); + } + + function _dataPointStorage(DataPoint dp) private view returns (DataPointStorage storage) { + DataPointStorage storage dps = dpStorages[dp]; + if (address(dps.dataIndexImplementation) == address(0)) { + revert UninitializedDataPoint(dp); + } + return dpStorages[dp]; + } + + function _tryDataPointStorage(DataPoint dp) private view returns (bool success, DataPointStorage storage) { + DataPointStorage storage dps = dpStorages[dp]; + if (address(dps.dataIndexImplementation) == address(0)) { + return (false, dps); + } + return (true, dps); + } +} diff --git a/assets/erc-7208/contracts/interfaces/IDataIndex.sol b/assets/erc-7208/contracts/interfaces/IDataIndex.sol new file mode 100644 index 0000000000..45dc3a6b29 --- /dev/null +++ b/assets/erc-7208/contracts/interfaces/IDataIndex.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../utils/DataPoints.sol"; + +/** + * @title Data Index interface + * @notice The interface defines functions to manage the access control of DataManagers to + * DataPoints as well as to the data related to these DataPoints in specific dataObjects + */ +interface IDataIndex { + /** + * @notice Verifies if DataManager is allowed to write in specific DataPoint + * @param dp Identifier of the DataPoint + * @param dm Address of DataManager + * @return if write access is allowed + */ + function isApprovedDataManager(DataPoint dp, address dm) external view returns (bool); + + /** + * @notice Defines if DataManager is allowed to write in specific DataPoint + * @param dp Identifier of the DataPoint + * @param dm Address of DataManager + * @param approved if DataManager should be approved for the DataPoint + * @dev Function SHOULD be restricted to DataPoint maintainer only + */ + function allowDataManager(DataPoint dp, address dm, bool approved) external; + + /** + * @notice Reads stored data + * @param dobj Identifier of DataObject + * @param dp Identifier of the DataPoint + * @param operation Read operation to execute on the data + * @param data Operation-specific data + * @return Operation-specific data + */ + function read(address dobj, DataPoint dp, bytes4 operation, bytes calldata data) external view returns (bytes memory); + + /** + * @notice Stores data + * @param dobj Identifier of DataObject + * @param dp Identifier of the DataPoint + * @param operation Write operation to execute on the data + * @param data Operation-specific data + * @return Operation-specific data (can be empty) + * @dev Function SHOULD be restricted to allowed DMs only + */ + function write(address dobj, DataPoint dp, bytes4 operation, bytes calldata data) external returns (bytes memory); +} diff --git a/assets/erc-7208/contracts/interfaces/IDataObject.sol b/assets/erc-7208/contracts/interfaces/IDataObject.sol new file mode 100644 index 0000000000..6f5430f14d --- /dev/null +++ b/assets/erc-7208/contracts/interfaces/IDataObject.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../utils/DataPoints.sol"; +import "./IDataIndex.sol"; + +/** + * @title Data Object Interface + * @notice Interface defines functions to manage the DataIndex implementation and the data + * stored in DataObjects and associated with DataPoints + */ +interface IDataObject { + /** + * @notice Reads stored data + * @param dp Identifier of the DataPoint + * @param operation Read operation to execute on the data + * @param data Operation-specific data + * @return Operation-specific data + */ + function read(DataPoint dp, bytes4 operation, bytes calldata data) external view returns (bytes memory); + + /** + * @notice Store data + * @param dp Identifier of the DataPoint + * @param operation Read operation to execute on the data + * @param data Operation-specific data + * @return Operation-specific data (can be empty) + */ + function write(DataPoint dp, bytes4 operation, bytes calldata data) external returns (bytes memory); + + /** + * @notice Sets DataIndex Implementation + * @param dp Identifier of the DataPoint + * @param newImpl address of the new DataIndex implementation + */ + function setDIImplementation(DataPoint dp, IDataIndex newImpl) external; +} diff --git a/assets/erc-7208/contracts/interfaces/IDataPointRegistry.sol b/assets/erc-7208/contracts/interfaces/IDataPointRegistry.sol new file mode 100644 index 0000000000..6e9483064d --- /dev/null +++ b/assets/erc-7208/contracts/interfaces/IDataPointRegistry.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {DataPoint} from "../utils/DataPoints.sol"; + +/** + * @title Data Point Registry Interface + * @notice Interface defines functions to manage creation, transfer and access control of DataPoints + */ +interface IDataPointRegistry { + /** + * @notice Event emitted when a DataPoint is allocated + * @param dp DataPoint identifier + * @param owner Owner of the DataPoint + */ + event DataPointAllocated(DataPoint indexed dp, address owner); + + /** + * @notice Event emitted when ownership of a DataPoint is transferred + * @param dp DataPoint identifier + * @param previousOwner Previous owner + * @param newOwner New owner + */ + event DataPointOwnershipTransferred(DataPoint indexed dp, address previousOwner, address newOwner); + + /** + * @notice Event emitted when Admin role is granted + * @param dp DataPoint identifier + * @param account Account granted with Admin role + */ + event DataPointAdminGranted(DataPoint indexed dp, address account); + + /** + * @notice Event emitted when Admin role is revoked + * @param dp DataPoint identifier + * @param account Account revoked from Admin role + */ + event DataPointAdminRevoked(DataPoint indexed dp, address account); + + /// @dev Error thrown when DataPoint allocation counter overflows + error CounterOverflow(); + + /// @dev Error thrown when native coin is sent in allocation + error NativeCoinDepositIsNotAccepted(); + + /** + * @notice Error thrown when caller is not the owner of the DataPoint + * @param dp DataPoint identifier + * @param owner Invalid owner + */ + error InvalidDataPointOwner(DataPoint dp, address owner); + + /** + * @notice Verifies if an address has an Admin role for a DataPoint + * @param dp DataPoint + * @param account Account to verify + */ + function isAdmin(DataPoint dp, address account) external view returns (bool); + + /** + * @notice Allocates a DataPoint to an owner + * @param owner Owner of the new DataPoint + * @dev Owner SHOULD be granted Admin role during allocation + */ + function allocate(address owner) external payable returns (DataPoint); + + /** + * @notice Transfers ownership of a DataPoint to a new owner + * @param dp DataPoint identifier + * @param newOwner New owner + */ + function transferOwnership(DataPoint dp, address newOwner) external; + + /** + * @notice Grant permission to grant/revoke other roles on the DataPoint inside an DataIndex Implementation + * This is useful if DataManagers are deployed during lifecycle of the application. + * @param dp DataPoint identifier + * @param account New admin + * @return If the role was granted (otherwise account already had the role) + */ + function grantAdminRole(DataPoint dp, address account) external returns (bool); + + /** + * @notice Revoke permission to grant/revoke other roles on the DataPoint inside an DataIndex Implementation + * @param dp DataPoint identifier + * @param account Old admin + * @dev If an owner revokes Admin role from himself, he can add it again + * @return If the role was revoked (otherwise account didn't had the role) + */ + function revokeAdminRole(DataPoint dp, address account) external returns (bool); +} diff --git a/assets/erc-7208/contracts/interfaces/IFractionTransferEventEmitter.sol b/assets/erc-7208/contracts/interfaces/IFractionTransferEventEmitter.sol new file mode 100644 index 0000000000..fd80a33a39 --- /dev/null +++ b/assets/erc-7208/contracts/interfaces/IFractionTransferEventEmitter.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @title Fraction Transfer Event Emitter interface + * @notice Interface defines functions to emit events when fractions are transferred + */ +interface IFractionTransferEventEmitter { + /// @dev Emmited when caller is not one of expected addresses + error WrongTransferNotificationSource(); + + /** + * @notice Notifies about a fraction transfer + * @param from Address from which the fraction is transferred + * @param to Address to which the fraction is transferred + * @param value Amount of the fraction transferred + * @dev Should emit an event with the information about the transfer + */ + function fractionTransferredNotify(address from, address to, uint256 value) external; +} diff --git a/assets/erc-7208/contracts/interfaces/IFungibleFractionsOperations.sol b/assets/erc-7208/contracts/interfaces/IFungibleFractionsOperations.sol new file mode 100644 index 0000000000..9442f1c3fa --- /dev/null +++ b/assets/erc-7208/contracts/interfaces/IFungibleFractionsOperations.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @title Fungible Fractions Operations Interface + * @notice Provides the operations of the FungibleFractionsDO to interact with + * fungible fractions tokens and their associated data + */ +interface IFungibleFractionsOperations { + /** + * @notice Operation used to get the balance of an account + * @param account The account address + * @param id The id of the token + * @return The balance of the account + */ + function balanceOf(address account, uint256 id) external view returns (uint256); + + /** + * @notice Operation used to get the balance of an account + * @param account The account address + * @param ids The ids of the tokens + * @return The balance of the account + */ + function balanceOfBatch(address account, uint256[] calldata ids) external view returns (uint256[] memory); + + /** + * @notice Operation used to get the balance of multiple accounts + * @param accounts The account addresses + * @param ids The ids of the tokens + * @return The balance of the accounts + */ + function balanceOfBatchAccounts(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); + + /** + * @notice Operation used to get the total supply of a token + * @param id The id of the token + * @return The total supply of the token + */ + function totalSupply(uint256 id) external view returns (uint256); + + /** + * @notice Operation used to get the total supply of all ids tokens + * @return The total supply of all ids tokens + */ + function totalSupplyAll() external view returns (uint256); + + /** + * @notice Operation used to check if an id exists + * @param id The id of the token + * @return True if the id exists, false otherwise + */ + function exists(uint256 id) external view returns (bool); + + /** + * @notice Operation used to transfer tokens from one account to another + * @param from The account to transfer from + * @param to The account to transfer to + * @param id The id of the token + * @param value The amount of tokens to transfer + */ + function transferFrom(address from, address to, uint256 id, uint256 value) external; + + /** + * @notice Operation used to transfer tokens from one account to another + * @param from The account to transfer from + * @param to The account to transfer to + * @param ids The ids of the tokens + * @param values The amounts of tokens to transfer + */ + function batchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values) external; + + /** + * @notice Operation used to mint tokens + * @param to The account to mint to + * @param id The id of the token + * @param value The amount of tokens to mint + */ + function mint(address to, uint256 id, uint256 value) external; + + /** + * @notice Operation used to burn tokens + * @param from The account to burn from + * @param id The id of the token + * @param value The amount of tokens to burn + */ + function burn(address from, uint256 id, uint256 value) external; + + /** + * @notice Operation used to mint tokens + * @param to The account to mint to + * @param ids The ids of the tokens + * @param values The amounts of tokens to mint + */ + function batchMint(address to, uint256[] calldata ids, uint256[] calldata values) external; + + /** + * @notice Operation used to burn tokens + * @param from The account to burn from + * @param ids The ids of the tokens + * @param values The amounts of tokens to burn + */ + function batchBurn(address from, uint256[] calldata ids, uint256[] calldata values) external; +} diff --git a/assets/erc-7208/contracts/interfaces/IIDManager.sol b/assets/erc-7208/contracts/interfaces/IIDManager.sol new file mode 100644 index 0000000000..ea162eb17f --- /dev/null +++ b/assets/erc-7208/contracts/interfaces/IIDManager.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {DataPoint} from "../utils/DataPoints.sol"; + +/** + * @title ID Manager Interface + * @notice Interface defines functions to build DataIndex user identifiers and get information about them + */ +interface IIDManager { + /** + * @notice Provides DataIndex id for a specific account for a specific DataPoint + * @param account Address of the user + * @param dp DataPoint the id should be linked with + * @return DataIndex identifier + * @dev If no token available, this function REVERTS + */ + function diid(address account, DataPoint dp) external view returns (bytes32); + + /** + * @notice Provides information about owner of specific DataIndex id + * @param diid DataIndex id to get info for + * @return chainid of owner's address + * @return owner's address + */ + function ownerOf(bytes32 diid) external view returns (uint32, address); +} diff --git a/assets/erc-7208/contracts/utils/ChainidTools.sol b/assets/erc-7208/contracts/utils/ChainidTools.sol new file mode 100644 index 0000000000..163b6a7877 --- /dev/null +++ b/assets/erc-7208/contracts/utils/ChainidTools.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @title ChainidTools library + * @notice This library provides helper to convert uint256 chainid provided by block.chainid to uint32 + * chainid used accross this DataIndex implementation + */ +library ChainidTools { + /// @dev Error thrown when chainid is not supported + error UnsupportedChain(uint256 chainId); + + /// @dev Error thrown when chainid is not the current chain + error UnexpectedChain(uint32 expected, uint32 requested); + + /// @dev Error thrown when chainid is not the expected chain + error DifferentChainExpected(uint256 chainId); + + /** + * @notice Converts block.chainid to uint32 chainid + * @return uint32 chainid + */ + function chainid() internal view returns (uint32) { + if (block.chainid < type(uint32).max) { + return uint32(block.chainid); + } + revert UnsupportedChain(block.chainid); + } + + /** + * @notice Requires current chain to be the same as requested + * @param chainId Requested chain ID + */ + function requireCurrentChain(uint32 chainId) internal view { + uint32 currentChain = uint32(block.chainid); + if (currentChain != chainId) revert UnexpectedChain(currentChain, chainId); + } + + /** + * @notice Requires current chain to be different than requested + * @param chainId Requested chain ID + */ + function requireNotCurrentChain(uint32 chainId) internal view { + if (block.chainid == 31337) return; // Allow LayerZero Endpoint Mock to be used on Hardhat testnet + uint32 currentChain = uint32(block.chainid); + if (currentChain == chainId) revert DifferentChainExpected(chainId); + } +} diff --git a/assets/erc-7208/contracts/utils/DataPoints.sol b/assets/erc-7208/contracts/utils/DataPoints.sol new file mode 100644 index 0000000000..a89b0c5023 --- /dev/null +++ b/assets/erc-7208/contracts/utils/DataPoints.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ChainidTools} from "./ChainidTools.sol"; + +/// @dev DataPoint is a 32 bytes structure which contains information about data point +type DataPoint is bytes32; + +/** + * DataPoint structure: + * 0xPPPPVVRRIIIIIIIIHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + * - Prefix (bytes4) + * -- PPPP - Type prefix (0x4450) - ASCII representation of letters "DP" + * -- VV - Version of DataPoint specification, currently 0x00 + * -- RR - Reserved byte (should be 0x00 in current specification) + * - Registry-local identifier + * -- IIIIIIII - 32 bit implementation-specific id of the DataPoint + * - Chain ID (bytes4) + * -- HHHHHHHH - 32 bit of chain identifier + * - Registry Address (bytes20) + * -- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Address of Registry which allocated the DataPoint + * + * !!! COMPATIBILITY REQUIREMENTS !!! + * - Registry address MUST be located in last 20 bytes of the DataPoint in ALL DataPoint implementations + * - PREFIX 0x44500000 SHOULD be used only by implementations with same DataPoint structure + */ + +/** + * @title DataPoints library + * @notice Library with utility functions to encode and decode DataPoint + */ +library DataPoints { + /// @dev represent PPPPVVRR prefix + bytes4 internal constant PREFIX = 0x44500000; + + /// @dev Error thrown when DataPoint structure is not supported + error UnsupportedDataPointStructure(); + + /** + * @notice Encode DataPoint + * @param registry Address of the registry which allocated the DataPoint + * @param id 32 bit implementation-specific id of the DataPoint + * @return Encoded DataPoint + */ + function encode(address registry, uint32 id) internal view returns (DataPoint) { + return + DataPoint.wrap( + bytes32((uint256(uint32(PREFIX)) << 224) | (uint256(id) << 192) | (uint256(ChainidTools.chainid()) << 160) | uint256(uint160(registry))) + ); + } + + /** + * @notice Decode DataPoint + * @param dp DataPoint to decode + * @return chainid Chain ID of the DataPoint + * @return registry Address of the registry which allocated the DataPoint + * @return id 32 bit implementation-specific id of the DataPoint + */ + function decode(DataPoint dp) internal pure returns (uint32 chainid, address registry, uint32 id) { + uint256 dpu = uint256(DataPoint.unwrap(dp)); + bytes4 prefix = bytes4(uint32(dpu >> 224)); + if (prefix != PREFIX) revert UnsupportedDataPointStructure(); + registry = address(uint160(dpu)); + chainid = uint32(dpu >> 160); + id = uint32(dpu >> 192); + } +} diff --git a/assets/erc-7208/contracts/utils/OmnichainAddresses.sol b/assets/erc-7208/contracts/utils/OmnichainAddresses.sol new file mode 100644 index 0000000000..25897074b6 --- /dev/null +++ b/assets/erc-7208/contracts/utils/OmnichainAddresses.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ChainidTools} from "./ChainidTools.sol"; + +/// @dev OmnichainAddress is a structure that represents address on specific chain +type OmnichainAddress is bytes32; + +/** + * OmnichainAddress structure: + * 0xPPPPVVRRRRRRRRRRHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + * - Prefix (bytes4): + * -- PPPP - Type prefix (0x4F41) - ASCII representation of letters "OA" + * -- VV - Version of OmnichainAddress specification, currently 0x00 + * -- RR - Reserved byte + * - Reserved bytes (bytes4) + * -- RRRRRRRR - Reserved bytes (should be 0x00000000 in current specification) + * - Chain ID (bytes4) + * -- HHHHHHHH - 32 bit of chain identifier + * - User Address (bytes20) + * -- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Address of the user + * + * Note: cheap conversion to `address` is possible: + * `address account = address(uint160(uint256(OmnichainAddress.unwrap(omnichainAddress))))` + * but it ignores chainid and prefix, so must be used with care + * + * !!! COMPATIBILITY REQUIREMENTS !!! + * - PREFIX 0x4F410000 SHOULD be used only by implementations with same OmnichainAddress structure + * - Requirements for other implementations: + * -- User Identifier MUST be persistent between compatible DataIndex implementations (so that user can use same ID in all compatible implementations) + * -- Any of compatible DataIndex implementation SHOULD be able to find owner of ID issued by any other compatible implementation + */ + +/** + * @title OmnichainAddresses library + * @notice Library with utility functions to encode and decode OmnichainAddress + */ +library OmnichainAddresses { + /// @dev represent PPPPVVRR prefix + bytes4 internal constant PREFIX = 0x4F410000; + + /// @dev Error thrown when OmnichainAddress structure is not supported + error UnsupportedOmnichainAddressesStructure(); + + /** + * @notice Encode OmnichainAddress + * @param account Address of the user + * @return Encoded OmnichainAddress + */ + function encode(address account) internal view returns (OmnichainAddress) { + return encode(ChainidTools.chainid(), account); + } + + /** + * @notice Encode OmnichainAddress + * @param chainid Chain ID to encode + * @param account Address of the user + * @return Encoded OmnichainAddress + */ + function encode(uint32 chainid, address account) internal pure returns (OmnichainAddress) { + return OmnichainAddress.wrap(bytes32((uint256(uint32(PREFIX)) << 224) | (uint256(chainid) << 160) | uint256(uint160(account)))); + } + + /** + * @notice Decode OmnichainAddress + * @param oa OmnichainAddress to decode + * @return chainid Chain ID of the OmnichainAddress + * @return account Address of the user + */ + function decode(OmnichainAddress oa) internal pure returns (uint32 chainid, address account) { + uint256 oau = uint256(OmnichainAddress.unwrap(oa)); + bytes4 prefix = bytes4(uint32(oau >> 224)); + if (prefix != PREFIX) revert UnsupportedOmnichainAddressesStructure(); + account = address(uint160(oau)); + chainid = uint32(oau >> 160); + } +} From e402021427d03ea0fc941838b64d9abf740754b4 Mon Sep 17 00:00:00 2001 From: Vectorized Date: Fri, 2 Aug 2024 12:56:18 +0800 Subject: [PATCH 15/79] Update ERC-7631: Move to Review Merged by EIP-Bot. --- ERCS/erc-7631.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/ERCS/erc-7631.md b/ERCS/erc-7631.md index 2f905685bf..8909007dbe 100644 --- a/ERCS/erc-7631.md +++ b/ERCS/erc-7631.md @@ -4,7 +4,7 @@ title: Dual Nature Token Pair description: A specification for a co-joined fungible and non-fungible token pair author: vectorized (@vectorized), Thomas (@0xth0mas), Quit (@quitcrypto), Michael Amadi (@AmadiMichael), cygaar (@cygaar), Harrison (@pop-punk) discussions-to: https://ethereum-magicians.org/t/erc-7631-dual-nature-token-pair/18796 -status: Draft +status: Review type: Standards Track category: ERC created: 2024-02-21 @@ -62,17 +62,24 @@ The ERC-20 contract MAY implement the following interface. interface IERC7631BaseNFTSkippable { /// @dev Implementations SHOULD emit this event when the skip NFT status /// of `owner` is updated to `status`. + /// + /// The purpose of this event is to signal to indexers that the + /// skip NFT status has been changed. + /// + /// For simplicity of implementation, + /// this event MAY be emitted even if the status is unchanged. event SkipNFTSet(address indexed owner, bool status); /// @dev Returns true if ERC-721 mints and transfers to `owner` SHOULD be - /// skipped during ERC-20 to ERC-721 synchronization. Otherwise false. + /// skipped during ERC-20 to ERC-721 synchronization. + /// Otherwise, returns false. /// /// This method MAY revert /// (e.g. contract not initialized, method not supported). /// /// If this method reverts: /// - Interacting code SHOULD interpret `setSkipNFT` functionality as - /// unavailable (and hide any functionality to call `setSkipNFT`). + /// unavailable and hide any functionality to call `setSkipNFT`. /// - The skip NFT status for `owner` SHOULD be interpreted as undefined. /// /// Once a true or false value has been returned for a given `owner`, @@ -123,7 +130,7 @@ The `getSkipNFT` and `setSkipNFT` methods MAY revert. As contracts compiled with The skip NFT methods allow accounts to avoid having ERC-721 tokens automatically minted to it whenever there is an ERC-20 transfer. -This is useful in the following situations: +They are helpful in the following situations: - Loading vesting contracts with large amounts ERC-20 tokens to be vested to many users. - Loading candy machine contracts with large amounts of ERC-20 tokens to sell ERC-721 tokens to customers. @@ -132,7 +139,9 @@ This is useful in the following situations: Including the skip NFT methods in the standard will: - Enable applications to conveniently display the option for users to skip NFTs. -- Enable applications to transfer any amount of ERC-20 tokens without the O(n) gas costs associated with minting multiple ERC-721 tokens, which could surpass the block gas limit. +- Enable applications to transfer any amount of ERC-20 tokens without the O(n) gas costs associated with minting multiple ERC-721 tokens, which can surpass the block gas limit. + +These methods are recommended even on EVM chains with low gas costs, because bulk automatic ERC-721 transfers can still surpass the block gas limit. A useful pattern is to make `getSkipNFT` return true by default if `owner` is a smart contract. From ff5a0ba13d4204e54e03e9a1b1f3f0c9bedbe017 Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Fri, 2 Aug 2024 10:29:55 +0200 Subject: [PATCH 16/79] Website: Fixed typos in events / added arguments to SettlementEvaluated event. Merged by EIP-Bot. --- ERCS/erc-6123.md | 10 ++--- assets/erc-6123/contracts/ERC20Settlement.sol | 13 +++--- assets/erc-6123/contracts/ISDC.sol | 44 ++++++++++--------- assets/erc-6123/contracts/SDCSingleTrade.sol | 4 +- .../SDCSingleTradePledgedBalance.sol | 19 ++++---- assets/erc-6123/test/SDCTests.js | 11 +++-- 6 files changed, 51 insertions(+), 50 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index 43986463a8..de138cbe3b 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -115,10 +115,10 @@ function afterTransfer(bool success, uint256 transactionData) external; #### Trade Termination: `requestTermination` -Allows an eligible party to request a mutual termination of the trade with the correspondig `tradeData` with a termination amount she is willing to pay and provide further termination terms (e.g. an XML) +Allows an eligible party to request a mutual termination of the trade with the correspondig `tradeId` with a termination amount she is willing to pay and provide further termination terms (e.g. an XML) ```solidity -function requestTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; +function requestTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; ``` #### Trade Termination: `confirmTradeTermination` @@ -126,7 +126,7 @@ function requestTradeTermination(string memory tradeData, int256 terminationPaym Allows an eligible party to confirm a previously requested (mutual) trade termination, including termination payment value and termination terms ```solidity -function confirmTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; +function confirmTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; ``` #### Trade Termination: `cancelTradeTermination` @@ -134,7 +134,7 @@ function confirmTradeTermination(string memory tradeData, int256 terminationPaym The party that initiated `requestTradeTermination` has the option to withdraw the request, e.g., in the case where the termination is not confirmed in a timely manner. ```solidity -function cancelTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; +function cancelTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; ``` ### Trade Events @@ -178,7 +178,7 @@ event TradeActivated(string tradeId); Emitted when a settlement is requested. May trigger the settlement phase. ```solidity -event SettlementRequested(address initiator, string tradeData, string lastSettlementData); +event SettlementRequested(address initiator, string tradeId, string lastSettlementData); ``` ### SettlementEvaluated diff --git a/assets/erc-6123/contracts/ERC20Settlement.sol b/assets/erc-6123/contracts/ERC20Settlement.sol index 5aedb06d25..bd63f3cf3e 100644 --- a/assets/erc-6123/contracts/ERC20Settlement.sol +++ b/assets/erc-6123/contracts/ERC20Settlement.sol @@ -4,6 +4,7 @@ pragma solidity >=0.7.0 <0.9.0; import "./ISDC.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; import "./IERC20Settlement.sol"; contract ERC20Settlement is ERC20, IERC20Settlement{ @@ -39,9 +40,9 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ function checkedTransfer(address to, uint256 value, uint256 transactionID) public onlySDC{ if ( balanceOf(sdcAddress) < value) - ISDC(sdcAddress).afterTransfer(false, transactionID); + ISDC(sdcAddress).afterTransfer(false, Strings.toString(transactionID)); else - ISDC(sdcAddress).afterTransfer(true, transactionID); + ISDC(sdcAddress).afterTransfer(true, Strings.toString(transactionID)); } function checkedTransferFrom(address from, address to, uint256 value, uint256 transactionID) external view onlySDC { @@ -54,14 +55,14 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ for(uint256 i = 0; i < values.length; i++) requiredBalance += values[i]; if (balanceOf(msg.sender) < requiredBalance){ - ISDC(sdcAddress).afterTransfer(false, transactionID); + ISDC(sdcAddress).afterTransfer(false, Strings.toString(transactionID)); return; } else{ for(uint256 i = 0; i < to.length; i++){ _transfer(sdcAddress,to[i],values[i]); } - ISDC(sdcAddress).afterTransfer(true, transactionID); + ISDC(sdcAddress).afterTransfer(true, Strings.toString(transactionID)); } } @@ -77,7 +78,7 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ totalRequiredBalance += values[j]; } if (balanceOf(fromAddress) < totalRequiredBalance){ - ISDC(sdcAddress).afterTransfer(false, transactionID); + ISDC(sdcAddress).afterTransfer(false, Strings.toString(transactionID)); return; } @@ -85,7 +86,7 @@ contract ERC20Settlement is ERC20, IERC20Settlement{ for(uint256 i = 0; i < to.length; i++){ _transfer(from[i],to[i],values[i]); } - ISDC(sdcAddress).afterTransfer(true, transactionID); + ISDC(sdcAddress).afterTransfer(true, Strings.toString(transactionID)); } } \ No newline at end of file diff --git a/assets/erc-6123/contracts/ISDC.sol b/assets/erc-6123/contracts/ISDC.sol index 90b299f72d..dddc9bc172 100644 --- a/assets/erc-6123/contracts/ISDC.sol +++ b/assets/erc-6123/contracts/ISDC.sol @@ -70,10 +70,14 @@ interface ISDC { /** * @dev Emitted when a new trade is incepted from a eligible counterparty * @param initiator is the address from which trade was incepted + * @param withParty is the party the inceptor wants to trade with * @param tradeId is the trade ID (e.g. generated internally) - * @param tradeData holding the trade parameters + * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param position is the position the inceptor has in that trade + * @param paymentAmount is the payment amount which can be positive or negative (viewed from the inceptor) + * @param initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) */ - event TradeIncepted(address initiator, string tradeId, string tradeData); + event TradeIncepted(address initiator, address withParty, string tradeId, string tradeData, int position, int256 paymentAmount, string initialSettlementData); /** * @dev Emitted when an incepted trade is confirmed by the opposite counterparty @@ -99,34 +103,38 @@ interface ISDC { /** * @dev Emitted when an active trade is terminated + * @param tradeId the trade identifier of the activated trade * @param cause string holding data associated with the termination, e.g. transactionData upon a failed transaction */ - event TradeTerminated(string cause); + event TradeTerminated(string tradeId, string cause); /* Events related to the settlement process */ /** - * @dev Emitted when Settlement phase is initiated + * @dev Emitted when a settlement gets requested + * @param initiator the address of the requesting party + * @param tradeData holding the stored trade data + * @param lastSettlementData holding the settlementdata from previous settlement (next settlement will be the increment of next valuation compared to former valuation) */ - event SettlementEvaluated(); + event SettlementRequested(address initiator, string tradeData, string lastSettlementData); /** - * @dev Emitted when settlement process has been finished + * @dev Emitted when Settlement has been valued and settlement phase is initiated + * @param initiator the address of the requesting party + * @param settlementAmount the settlement amount. If settlementAmount > 0 then receivingParty receives this amount from other party. If settlementAmount < 0 then other party receives -settlementAmount from receivingParty. + * @param settlementData. the tripple (product, previousSettlementData, settlementData) determines the settlementAmount. */ - event SettlementTranfered(string transactionData); + event SettlementEvaluated(address initiator, int256 settlementAmount, string settlementData); /** * @dev Emitted when settlement process has been finished */ - event SettlementFailed(string transactionData); + event SettlementTransferred(string transactionData); /** - * @dev Emitted when a settlement gets requested - * @param initiator the address of the requesting party - * @param tradeData holding the stored trade data - * @param lastSettlementData holding the settlementdata from previous settlement (next settlement will be the increment of next valuation compared to former valuation) + * @dev Emitted when settlement process has been finished */ - event SettlementRequested(address initiator, string tradeData, string lastSettlementData); + event SettlementFailed(string transactionData); /* Events related to trade termination */ @@ -154,12 +162,6 @@ interface ISDC { */ event TradeTerminationCanceled(address cpAddress, string tradeId, string terminationTerms); - /** - * @dev Emitted when trade processing is halted - * @param message of what has happened - */ - event ProcessHalted(string message); - /*------------------------------------------- FUNCTIONALITY ---------------------------------------------------------------------------------------*/ /// Trade Inception @@ -218,9 +220,9 @@ interface ISDC { * @notice May get called from outside to to finish a transfer (callback). The trade decides on how to proceed based on success flag * @param success tells the protocol whether transfer was successful * @param transactionData data associtated with the transfer, will be emitted via the events. - * @dev emit a {SettlementTranfered} or a {SettlementFailed} event. May emit a {TradeTerminated} event. + * @dev emit a {SettlementTransferred} or a {SettlementFailed} event. May emit a {TradeTerminated} event. */ - function afterTransfer(bool success, uint256 transactionData) external; + function afterTransfer(bool success, string memory transactionData) external; /// Trade termination diff --git a/assets/erc-6123/contracts/SDCSingleTrade.sol b/assets/erc-6123/contracts/SDCSingleTrade.sol index 71c3eba737..c6dc890ae3 100644 --- a/assets/erc-6123/contracts/SDCSingleTrade.sol +++ b/assets/erc-6123/contracts/SDCSingleTrade.sol @@ -19,7 +19,7 @@ import "./ERC20Settlement.sol"; * - upon termination all remaining 'locked' amounts will be transferred back to the counterparties */ -abstract contract SDC is ISDC { +abstract contract SDCSingleTrade is ISDC { /* * Trade States */ @@ -143,7 +143,7 @@ abstract contract SDC is ISDC { upfrontPayment = _position == 1 ? _paymentAmount : -_paymentAmount; // upfrontPayment is saved with view on the receiving party tradeID = Strings.toString(transactionHash); tradeData = _tradeData; // Set trade data to enable querying already in inception state - emit TradeIncepted(msg.sender, tradeID, _tradeData); + emit TradeIncepted(msg.sender, _withParty, tradeID, _tradeData, _position, _paymentAmount, _initialSettlementData); } /* diff --git a/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol index 0268780714..265512764c 100644 --- a/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol +++ b/assets/erc-6123/contracts/SDCSingleTradePledgedBalance.sol @@ -35,8 +35,7 @@ import "./ERC20Settlement.sol"; *-------------------------------------* */ -contract SDCPledgedBalance is SDC { - +contract SDCSingleTradePledgedBalance is SDCSingleTrade { struct MarginRequirement { uint256 buffer; @@ -54,7 +53,7 @@ contract SDCPledgedBalance is SDC { address _settlementToken, uint256 _initialBuffer, // m uint256 _initalTerminationFee // p - ) SDC(_party1,_party2,_settlementToken) { + ) SDCSingleTrade(_party1,_party2,_settlementToken) { marginRequirements[party1] = MarginRequirement(_initialBuffer, _initalTerminationFee); marginRequirements[party2] = MarginRequirement(_initialBuffer, _initalTerminationFee); } @@ -87,7 +86,7 @@ contract SDCPledgedBalance is SDC { address[] memory to = new address[](1); uint256[] memory amounts = new uint256[](1); from[0] = settlementPayer; to[0] = otherParty(settlementPayer); amounts[0] = transferAmount; - emit SettlementEvaluated(); + emit SettlementEvaluated(msg.sender, settlementAmount, _settlementData); setTradeState(TradeState.InTransfer); settlementToken.checkedBatchTransferFrom(from,to,amounts,transactionID); } @@ -96,7 +95,7 @@ contract SDCPledgedBalance is SDC { * afterTransfer processes SDC depending on success of the respective payment and depending on the current trade state * Good Case: state will be settled, failed settlement will trigger the pledge balance transfer and termination */ - function afterTransfer(bool success, uint256 transactionHash) external override { + function afterTransfer(bool success, string memory transactionHash) external override { if ( inStateConfirmed()){ if (success){ setTradeState(TradeState.Settled); @@ -104,28 +103,28 @@ contract SDCPledgedBalance is SDC { } else{ setTradeState(TradeState.Terminated); - emit TradeTerminated("Upfront Transfer Failure"); + emit TradeTerminated(tradeID, "Upfront Transfer Failure"); } } else if ( inStateTransfer() ){ if (success){ setTradeState(TradeState.Settled); - emit SettlementTranfered("Settlement Settled - Pledge Transfer"); + emit SettlementTransferred("Settlement Settled - Pledge Transfer"); } else{ // Settlement & Pledge Case: transferAmount is transferred from SDC balance (i.e. pledged balance). int256 settlementAmount = settlementAmounts[settlementAmounts.length-1]; setTradeState(TradeState.InTermination); processTerminationWithPledge(settlementAmount); - emit TradeTerminated("Settlement Failed - Pledge Transfer"); + emit TradeTerminated(tradeID, "Settlement Failed - Pledge Transfer"); } } else if( inStateTermination() ){ if (success){ setTradeState(TradeState.Terminated); - emit TradeTerminated("Trade terminated sucessfully"); + emit TradeTerminated(tradeID, "Trade terminated sucessfully"); } else{ - emit TradeTerminated("Mutual Termination failed - Pledge Transfer"); + emit TradeTerminated(tradeID, "Mutual Termination failed - Pledge Transfer"); processTerminationWithPledge(getTerminationPayment()); } } diff --git a/assets/erc-6123/test/SDCTests.js b/assets/erc-6123/test/SDCTests.js index 180231a0f3..6351c12b47 100644 --- a/assets/erc-6123/test/SDCTests.js +++ b/assets/erc-6123/test/SDCTests.js @@ -41,13 +41,12 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { counterparty1 = _counterparty1; counterparty2 = _counterparty2; ERC20Factory = await ethers.getContractFactory("ERC20Settlement"); - SDCFactory = await ethers.getContractFactory("SDCPledgedBalance"); + SDCFactory = await ethers.getContractFactory("SDCSingleTradePledgedBalance"); //oken = await ERC20Factory.deploy(); // await token.deployed(); }); - it("1. Counterparties incept and confirm a trade successfully, Upfront is transferred from CP1 to CP2", async () => { let token = await ERC20Factory.deploy(); await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); @@ -187,7 +186,7 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, upfront, "initialMarketData"); const receipt = await incept_call.wait(); const event = receipt.events.find(event => event.event === 'TradeIncepted'); - const trade_id = event.args[1]; + const trade_id = event.args[2]; const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, -upfront, "initialMarketData"); await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, terminationPayment, "terminationTerms"); @@ -212,7 +211,7 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); const receipt = await incept_call.wait(); const event = receipt.events.find(event => event.event === 'TradeIncepted'); - const trade_id = event.args[1]; + const trade_id = event.args[2]; const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); const terminate_call = await sdc.connect(counterparty2).requestTradeTermination(trade_id, -terminationPayment, "terminationTerms"); const confirm_terminate_call = await sdc.connect(counterparty1).confirmTradeTermination(trade_id, +terminationPayment, "terminationTerms"); @@ -229,7 +228,7 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); const receipt = await incept_call.wait(); const event = receipt.events.find(event => event.event === 'TradeIncepted'); - const trade_id = event.args[1]; + const trade_id = event.args[2]; const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, -terminationPayment, "terminationTerms"); const confirm_terminate_call = await sdc.connect(counterparty2).confirmTradeTermination(trade_id, +terminationPayment, "terminationTerms"); @@ -305,7 +304,7 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); const receipt = await incept_call.wait(); const event = receipt.events.find(event => event.event === 'TradeIncepted'); - const trade_id = event.args[1]; + const trade_id = event.args[2]; const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); await expect(confirm_call).to.emit(sdc, "TradeConfirmed"); const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, 10000000, "terminationTerms"); From 802224efa51f71c777a8b496e27159cb0a4cb1f7 Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Fri, 2 Aug 2024 18:01:00 +0200 Subject: [PATCH 17/79] ERC-6123: small refactor rename SDC.sol to SDCSingleTrade.sol Merged by EIP-Bot. --- assets/erc-6123/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/erc-6123/README.md b/assets/erc-6123/README.md index 8688af6511..4011a0d456 100644 --- a/assets/erc-6123/README.md +++ b/assets/erc-6123/README.md @@ -11,8 +11,8 @@ We provide the essential steps to compile the contracts and run the provided uni ### Provided Contracts and Tests - `contracts/ISDC.sol` - Interface contract -- `contracts/SDC.sol` - SDC abstract contract for an OTC Derivative -- `contracts/SDCPledgedBalance.sol` - SDC full implementation for an OTC Derivative +- `contracts/SDCSingleTrade.sol` - SDC abstract contract for an OTC Derivative (single trade case only) +- `contracts/SDCSingleTradePledgedBalance.sol` - SDC full implementation for an OTC Derivative (single trade case only) - `contracts/IERC20Settlement.sol` - Interface (extending the ERC-20) for settlement tokens used in `SDCPledgedBalance`. - `contracts/ERC20Settlement.sol` - Mintable settlement token contract implementing `IERC20Settlement` for unit tests - `test/SDCTests.js` - Unit tests for the life-cycle of the sdc implementation From a6f10b4bf9b7ef55c4ce6d58ee63bf0b7eebe9e9 Mon Sep 17 00:00:00 2001 From: Lukas <36800180+lukasrosario@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:04:26 -0400 Subject: [PATCH 18/79] Update ERC-7677: chain id update Merged by EIP-Bot. --- ERCS/erc-7677.md | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/ERCS/erc-7677.md b/ERCS/erc-7677.md index 8c155c41f4..528f0e279d 100644 --- a/ERCS/erc-7677.md +++ b/ERCS/erc-7677.md @@ -242,15 +242,18 @@ The `paymasterService` capability is implemented by both apps and wallets. #### App Implementation -Apps need to give wallets a paymaster service URL they can make the above RPC calls to. They can do this using the `paymasterService` capability as part of an [EIP-5792](./eip-5792.md) `wallet_sendCalls` call. +Apps need to give wallets paymaster service URLs they can make the above RPC calls to. They can do this using the `paymasterService` capability as part of an [EIP-5792](./eip-5792.md) `wallet_sendCalls` call. ##### `wallet_sendCalls` Paymaster Capability Specification ```typescript -type PaymasterCapabilityParams = { - url: string; - context: Record; -} +type PaymasterCapabilityParams = Record< + `0x${string}`, // Chain ID + { + url: string; // Paymaster service URL for provided chain ID + context: Record; // Additional data defined by paymaster service providers + } +>; ``` ###### `wallet_sendCalls` Example Parameters @@ -259,25 +262,34 @@ type PaymasterCapabilityParams = { [ { "version": "1.0", - "chainId": "0x01", "from": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", "calls": [ { "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", "value": "0x9184e72a", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", + "chainId": "0x01" }, { "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", "value": "0x182183", - "data": "0xfbadbaf01" + "data": "0xfbadbaf01", + "chainId": "0x2105" } ], "capabilities": { "paymasterService": { - "url": "https://...", - "context": { - "policyId": "962b252c-a726-4a37-8d86-333ce0a07299" + "0x01": { + "url": "https://...", + "context": { + "policyId": "962b252c-a726-4a37-8d86-333ce0a07299" + } + }, + "0x2105": { + "url": "https://...", + "context": { + "policyId": "0a268db9-3243-4178-b1bd-d9b67a47d37b" + } } } } @@ -285,7 +297,7 @@ type PaymasterCapabilityParams = { ] ``` -The wallet will then make the above paymaster RPC calls to the URL specified in the `paymasterService` capability field. +The wallet will then make the above paymaster RPC calls to the URLs specified in the `paymasterService` capability field. #### Wallet Implementation From 2922ed25ce1a849e23735c109c175688088064df Mon Sep 17 00:00:00 2001 From: James Brown Date: Mon, 5 Aug 2024 12:18:11 +1000 Subject: [PATCH 19/79] Add ERC: Permissionless Script Registry Merged by EIP-Bot. --- ERCS/erc-7738.md | 154 + assets/erc-7738/.gitignore | 17 + .../contracts/DecentralisedRegistry.sol | 90 + .../DecentralisedRegistryPermissioned.sol | 130 + assets/erc-7738/contracts/IERC7738.sol | 17 + assets/erc-7738/contracts/stakingToken.sol | 48 + assets/erc-7738/hardhat.config.ts | 32 + assets/erc-7738/ignition/modules/Lock.ts | 17 + assets/erc-7738/package-lock.json | 6944 +++++++++++++++++ assets/erc-7738/package.json | 24 + .../test/DecentralisedRegistry.test.ts | 151 + .../test/PermissionedRegistry.test.ts | 111 + assets/erc-7738/tsconfig.json | 11 + 13 files changed, 7746 insertions(+) create mode 100644 ERCS/erc-7738.md create mode 100644 assets/erc-7738/.gitignore create mode 100644 assets/erc-7738/contracts/DecentralisedRegistry.sol create mode 100644 assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol create mode 100644 assets/erc-7738/contracts/IERC7738.sol create mode 100644 assets/erc-7738/contracts/stakingToken.sol create mode 100644 assets/erc-7738/hardhat.config.ts create mode 100644 assets/erc-7738/ignition/modules/Lock.ts create mode 100644 assets/erc-7738/package-lock.json create mode 100644 assets/erc-7738/package.json create mode 100644 assets/erc-7738/test/DecentralisedRegistry.test.ts create mode 100644 assets/erc-7738/test/PermissionedRegistry.test.ts create mode 100644 assets/erc-7738/tsconfig.json diff --git a/ERCS/erc-7738.md b/ERCS/erc-7738.md new file mode 100644 index 0000000000..3d29b72003 --- /dev/null +++ b/ERCS/erc-7738.md @@ -0,0 +1,154 @@ +--- +eip: 7738 +title: Permissionless Script Registry +description: Permissionless registry to fetch executable scripts for contracts +author: Victor Zhang (@zhangzhongnan928), James Brown (@JamesSmartCell) +discussions-to: https://ethereum-magicians.org/t/erc-7738-permissionless-script-registry/20503 +status: Draft +type: Standards Track +category: ERC +created: 2024-07-01 +requires: 173 +--- +## Abstract + +This EIP provides a means to create a standard registry for locating executable scripts associated with the token. + +## Motivation + +[ERC-5169](./eip-5169.md) provides a client script lookup method for contracts. This requires the contract to have implemented the `ERC-5169` interface at the time of construction (or allow an upgrade path). + +This proposal outlines a contract that can supply prototype and certified scripts. The contract would be a multichain singleton instance that would be deployed at identical addresses on supported chains. + +### Overview + +The registry contract will supply a set of URI links for a given contract address. These URI links point to script programs that can be fetched by a wallet, viewer or mini-dapp. + +The pointers can be set permissionlessly using a setter in the registry contract. + +## Specification + +The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. + +The contract MUST implement the `IERC7738` interface. +The contract MUST emit the `ScriptUpdate` event when the script is updated. +The contract SHOULD order the `scriptURI` returned so that the `ERC-173` `owner()` of the contract's script entries are returned first (in the case of simple implementations the wallet will pick the first `scriptURI` returned). +The contract SHOULD provide a means to page through entries if there are a large number of scriptURI entries. + +```solidity +interface IERC7738 { + /// @dev This event emits when the scriptURI is updated, + /// so wallets implementing this interface can update a cached script + event ScriptUpdate(address indexed contractAddress, string[] newScriptURI); + + /// @notice Get the scriptURI for the contract + /// @return The scriptURI + function scriptURI(address contractAddress) external view returns (string[] memory); + + /// @notice Update the scriptURI + /// emits event ScriptUpdate(address indexed contractAddress, scriptURI memory newScriptURI); + function setScriptURI(address contractAddress, string[] memory scriptURIList) external; +} +``` + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +## Rationale + +This method allows contracts written without the [ERC-5169](./eip-5169.md) interface to associate scripts with themselves, and avoids the need for a centralised online server, with subsequent need for security and the requires an organisation to become a gatekeeper for the database. + +## Test Cases + +Hardhat contract and test scripts for two implementations can be found in the asset folder. + +## Reference Implementation + +```solidity +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract DecentralisedRegistry is IERC7738 { + struct ScriptEntry { + mapping(address => string[]) scriptURIs; + address[] addrList; + } + + mapping(address => ScriptEntry) private _scriptURIs; + + function setScriptURI( + address contractAddress, + string[] memory scriptURIList + ) public { + require (scriptURIList.length > 0, "> 0 entries required in scriptURIList"); + bool isOwnerOrExistingEntry = Ownable(contractAddress).owner() == msg.sender + || _scriptURIs[contractAddress].scriptURIs[msg.sender].length > 0; + _scriptURIs[contractAddress].scriptURIs[msg.sender] = scriptURIList; + if (!isOwnerOrExistingEntry) { + _scriptURIs[contractAddress].addrList.push(msg.sender); + } + + emit ScriptUpdate(contractAddress, msg.sender, scriptURIList); + } + + // Return the list of scriptURI for this contract. + // Order the return list so `Owner()` assigned scripts are first in the list + function scriptURI( + address contractAddress + ) public view returns (string[] memory) { + //build scriptURI return list, owner first + address contractOwner = Ownable(contractAddress).owner(); + address[] memory addrList = _scriptURIs[contractAddress].addrList; + uint256 i; + + //now calculate list length + uint256 listLen = _scriptURIs[contractAddress].scriptURIs[contractOwner].length; + for (i = 0; i < addrList.length; i++) { + listLen += _scriptURIs[contractAddress].scriptURIs[addrList[i]].length; + } + + string[] memory ownerScripts = new string[](listLen); + + // Add owner scripts + uint256 scriptIndex = _addScriptURIs(contractOwner, contractAddress, ownerScripts, 0); + + // Add remainder scripts + for (uint256 i = 0; i < addrList.length; i++) { + scriptIndex = _addScriptURIs(addrList[i], contractAddress, ownerScripts, scriptIndex); + } + + return ownerScripts; + } + + function _addScriptURIs( + address user, + address contractAddress, + string[] memory ownerScripts, + uint256 scriptIndex + ) internal view returns (uint256) { + for (uint256 j = 0; j < _scriptURIs[contractAddress].scriptURIs[user].length; j++) { + string memory thisScriptURI = _scriptURIs[contractAddress].scriptURIs[user][j]; + if (bytes(thisScriptURI).length > 0) { + ownerScripts[scriptIndex++] = thisScriptURI; + } + } + return scriptIndex; + } +} +``` + +## Security Considerations + +The scripts provided could be authenticated in various ways: + +1. The target contract which the setter specifies implements the [ERC-173](./eip-173.md) `Ownable` interface. Once the script is fetched, the signature can be verified to match the Owner(). In the case of TokenScript this can be checked by a dapp or wallet using the TokenScript SDK, the TokenScript online verification service, or by extracting the signature from the XML, taking a keccak256 of the script and ecrecover the signing key address. +2. If the contract does not implement Ownable, further steps can be taken: + a. The hosting app/wallet can acertain the deployment key using 3rd party API or block explorer. The implementing wallet, dapp or viewer would then check the signature matches this deployment key. + b. Signing keys could be pre-authenticated by a hosting app, using an embedded keychain. + c. A governance token could allow a script council to authenticate requests to set and validate keys. + +If these criteria are not met: +- For mainnet implementations the implementing wallet should be cautious about using the script - it would be at the app and/or user's discretion. +- For testnets, it is acceptable to allow the script to function, at the discretion of the wallet provider. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/assets/erc-7738/.gitignore b/assets/erc-7738/.gitignore new file mode 100644 index 0000000000..e8c12ff4fe --- /dev/null +++ b/assets/erc-7738/.gitignore @@ -0,0 +1,17 @@ +node_modules +.env + +# Hardhat files +/cache +/artifacts + +# TypeChain files +/typechain +/typechain-types + +# solidity-coverage files +/coverage +/coverage.json + +# Hardhat Ignition default folder for deployments against a local node +ignition/deployments/chain-31337 diff --git a/assets/erc-7738/contracts/DecentralisedRegistry.sol b/assets/erc-7738/contracts/DecentralisedRegistry.sol new file mode 100644 index 0000000000..2bbb2cab59 --- /dev/null +++ b/assets/erc-7738/contracts/DecentralisedRegistry.sol @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "./IERC7738.sol"; + +contract DecentralisedRegistry is IERC7738 { + struct ScriptEntry { + mapping(address => string[]) scriptURIs; + address[] addrList; + } + + uint256 public constant MAX_PAGE_SIZE = 500; + mapping(address => ScriptEntry) private _scriptURIs; + + function setScriptURI( + address contractAddress, + string[] memory scriptURIList + ) public { + require (scriptURIList.length > 0, "> 0 entries required in scriptURIList"); + bool isOwnerOrExistingEntry = Ownable(contractAddress).owner() == msg.sender + || _scriptURIs[contractAddress].scriptURIs[msg.sender].length > 0; + _scriptURIs[contractAddress].scriptURIs[msg.sender] = scriptURIList; + if (!isOwnerOrExistingEntry) { + _scriptURIs[contractAddress].addrList.push(msg.sender); + } + + emit ScriptUpdate(contractAddress, msg.sender, scriptURIList); + } + + function scriptURI( + address contractAddress + ) public view returns (string[] memory) { + return scriptURI(contractAddress, 1, MAX_PAGE_SIZE); + } + + function scriptURI(address contractAddress, uint256 page, uint256 pageSize) public view returns (string[] memory ownerScripts) { + require(page > 0 && pageSize > 0 && pageSize <= MAX_PAGE_SIZE, "Page >= 1 and pageSize <= MAX_PAGE_SIZE"); + + address contractOwner = Ownable(contractAddress).owner(); + address[] memory addrList = _scriptURIs[contractAddress].addrList; + uint256 startPoint = pageSize * (page - 1); + + uint256 listLen = _scriptURIs[contractAddress].scriptURIs[contractOwner].length; + for (uint256 i = 0; i < addrList.length; i++) { + listLen += _scriptURIs[contractAddress].scriptURIs[addrList[i]].length; + } + + uint256 arrayLen = listLen < pageSize ? listLen : pageSize; + ownerScripts = new string[](arrayLen); + uint256 scriptIndex = 0; + uint256 currentIndex = 0; + + if (startPoint >= listLen) { + return new string[](0) ; + } + + // Add owner scriptURIs + (scriptIndex, currentIndex) = _addScriptURIs(contractOwner, contractAddress, startPoint, scriptIndex, pageSize, ownerScripts, currentIndex); + + // Add remainder of scriptURIs + for (uint256 i = 0; i < addrList.length && scriptIndex < pageSize; i++) { + (scriptIndex, currentIndex) = _addScriptURIs(addrList[i], contractAddress, startPoint, scriptIndex, pageSize, ownerScripts, currentIndex); + } + } + + function _addScriptURIs( + address user, + address contractAddress, + uint256 startPoint, + uint256 scriptIndex, + uint256 pageSize, + string[] memory ownerScripts, + uint256 currentIndex + ) internal view returns (uint256, uint256) { + for (uint256 j = 0; j < _scriptURIs[contractAddress].scriptURIs[user].length; j++) { + string memory thisScriptURI = _scriptURIs[contractAddress].scriptURIs[user][j]; + if (bytes(thisScriptURI).length > 0) { + if (currentIndex >= startPoint) { + ownerScripts[scriptIndex++] = thisScriptURI; + } + if (scriptIndex >= pageSize) { + break; + } + } + currentIndex++; + } + return (scriptIndex, currentIndex); + } +} diff --git a/assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol b/assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol new file mode 100644 index 0000000000..9904140fb7 --- /dev/null +++ b/assets/erc-7738/contracts/DecentralisedRegistryPermissioned.sol @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "./IERC7738.sol"; + +contract DecentralisedRegistryPermissioned is IERC7738 { + struct ScriptEntry { + string[] scriptURIs; + address[] delegateSigners; // list of authenticated addresses approved by owner + address owner; // provides a latch so that 3rd parties can create TokenScript entries + } + + mapping(address => ScriptEntry) private _scriptURIs; + + event RegisterOwner( + address indexed contractAddress, + address indexed newOwner + ); + event AddDelegateSigner( + address indexed contractAddress, + address indexed newDelegate + ); + event RevokeDelegateSigner( + address indexed contractAddress, + address indexed revokedDelegate + ); + + function scriptURI( + address contractAddress + ) public view returns (string[] memory) { + return _scriptURIs[contractAddress].scriptURIs; + } + + function setScriptURI( + address contractAddress, + string[] memory scriptURIList + ) public { + // in order to set scriptURI array, the sender must adhere to the following rules: + require( + isDelegateOrOwner(contractAddress, msg.sender), + "Not authorized" + ); + + emit ScriptUpdate(contractAddress, msg.sender, scriptURIList); + _scriptURIs[contractAddress].scriptURIs = scriptURIList; + } + + function registerOwner(address contractAddress) public { + ScriptEntry storage existingEntry = _scriptURIs[contractAddress]; + address contractOwner = Ownable(contractAddress).owner(); + address sender = msg.sender; + require(existingEntry.owner != sender, "Already set to this owner"); + require( + existingEntry.owner == address(0) || sender == contractOwner, + "Not authorized" + ); + emit RegisterOwner(contractAddress, sender); + existingEntry.owner = sender; + } + + function isDelegateOrOwner( + address contractAddress, + address check + ) public view returns (bool) { + ScriptEntry memory existingEntry = _scriptURIs[contractAddress]; + if (check == Ownable(contractAddress).owner()) { + return true; + } + uint256 length = existingEntry.delegateSigners.length; + for (uint256 i = 0; i < length; ) { + if (existingEntry.delegateSigners[i] == check) { + return true; + } + unchecked { + i++; + } + } + return false; + } + + function getDelegateIndex( + address contractAddress, + address check + ) public view returns (int256) { + ScriptEntry memory existingEntry = _scriptURIs[contractAddress]; + uint256 length = existingEntry.delegateSigners.length; + for (uint256 i = 0; i < length; ) { + if (existingEntry.delegateSigners[i] == check) { + return int256(i); + } + unchecked { + i++; + } + } + return -1; + } + + function addDelegateSigner( + address contractAddress, + address newSigner + ) public { + require( + msg.sender == Ownable(contractAddress).owner(), + "Contract Owner only" + ); + require( + getDelegateIndex(contractAddress, newSigner) < 0, + "Already a delegate signer" + ); + emit AddDelegateSigner(contractAddress, newSigner); + _scriptURIs[contractAddress].delegateSigners.push(newSigner); + } + + function revokeDelegateSigner( + address contractAddress, + address signer + ) public { + int256 delegateIndex = getDelegateIndex(contractAddress, signer); + require( + msg.sender == Ownable(contractAddress).owner(), + "Contract Owner only" + ); + require(delegateIndex > -1, "Unable to revoke unknown signer"); + emit RevokeDelegateSigner(contractAddress, signer); + delete _scriptURIs[contractAddress].delegateSigners[ + uint256(delegateIndex) + ]; + } +} diff --git a/assets/erc-7738/contracts/IERC7738.sol b/assets/erc-7738/contracts/IERC7738.sol new file mode 100644 index 0000000000..647caed76d --- /dev/null +++ b/assets/erc-7738/contracts/IERC7738.sol @@ -0,0 +1,17 @@ + +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; +interface IERC7738 { + /// @dev This event emits when the scriptURI is updated, + /// so wallets implementing this interface can update a cached script + event ScriptUpdate(address indexed contractAddress, address indexed setter, string[] newScriptURI); + + /// @notice Get the scriptURI for the contract + /// @return The scriptURI + function scriptURI(address contractAddress) external view returns (string[] memory); + + /// @notice Update the scriptURI + /// emits event ScriptUpdate(address indexed contractAddress, scriptURI memory newScriptURI); + function setScriptURI(address contractAddress, string[] memory scriptURIList) external; +} \ No newline at end of file diff --git a/assets/erc-7738/contracts/stakingToken.sol b/assets/erc-7738/contracts/stakingToken.sol new file mode 100644 index 0000000000..60d1c08dea --- /dev/null +++ b/assets/erc-7738/contracts/stakingToken.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +// Compatible with OpenZeppelin Contracts ^5.0.0 +pragma solidity ^0.8.24; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract StakingToken is ERC721, ERC721Enumerable, Ownable { + uint256 private _nextTokenId; + + constructor() + ERC721("StakingToken", "STK") + Ownable(msg.sender) + { + safeMint(); + } + + function safeMint() public { + uint256 tokenId = _nextTokenId++; + _safeMint(msg.sender, tokenId); + } + + // The following functions are overrides required by Solidity. + function _update(address to, uint256 tokenId, address auth) + internal + override(ERC721, ERC721Enumerable) + returns (address) + { + return super._update(to, tokenId, auth); + } + + function _increaseBalance(address account, uint128 value) + internal + override(ERC721, ERC721Enumerable) + { + super._increaseBalance(account, value); + } + + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC721, ERC721Enumerable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} \ No newline at end of file diff --git a/assets/erc-7738/hardhat.config.ts b/assets/erc-7738/hardhat.config.ts new file mode 100644 index 0000000000..5b44ba3649 --- /dev/null +++ b/assets/erc-7738/hardhat.config.ts @@ -0,0 +1,32 @@ +import "dotenv/config" +import { HardhatUserConfig } from "hardhat/config" +import "@nomicfoundation/hardhat-toolbox" +import "hardhat-gas-reporter" + +let { PRIVATE_KEY, INFURA_KEY, ETHERSCAN_API_KEY } = process.env; + +const config: HardhatUserConfig = { + solidity: { compilers: [{ version: "0.8.24" }, { version: "0.8.24" }] }, + networks: { + mainnet: { + url: `https://mainnet.infura.io/v3/${INFURA_KEY}`, + accounts: [`${PRIVATE_KEY}`] + }, + sepolia: { + url: `https://sepolia.infura.io/v3/${INFURA_KEY}`, + accounts: [`${PRIVATE_KEY}`], + }, + mumbai: { + url: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`, + accounts: [`${PRIVATE_KEY}`] + }, + hardhat: { + gasPrice: 100000000000, + } + }, + etherscan: { + apiKey: `${ETHERSCAN_API_KEY}` //for contract verify + } +} + +export default config diff --git a/assets/erc-7738/ignition/modules/Lock.ts b/assets/erc-7738/ignition/modules/Lock.ts new file mode 100644 index 0000000000..eda0eba45b --- /dev/null +++ b/assets/erc-7738/ignition/modules/Lock.ts @@ -0,0 +1,17 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +const JAN_1ST_2030 = 1893456000; +const ONE_GWEI: bigint = 1_000_000_000n; + +const LockModule = buildModule("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); + const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); + +export default LockModule; diff --git a/assets/erc-7738/package-lock.json b/assets/erc-7738/package-lock.json new file mode 100644 index 0000000000..7b67bc2db6 --- /dev/null +++ b/assets/erc-7738/package-lock.json @@ -0,0 +1,6944 @@ +{ + "name": "hardhat", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hardhat", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@openzeppelin/contracts": "^5.0.2", + "dotenv": "^16.4.5", + "ethers": "^6.13.1", + "hardhat": "^2.22.6", + "stl-contracts": "^2.5.1" + }, + "devDependencies": { + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", + "@nomicfoundation/hardhat-toolbox": "^5.0.0" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true, + "peer": true + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "devOptional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomicfoundation/edr": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.4.1.tgz", + "integrity": "sha512-NgrMo2rI9r28uidumvd+K2/AJLdxtXsUlJr3hj/pM6S1FCd/HiWaLeLa/cjCVPcE2u1rYAa3W6UFxLCB7S5Dhw==", + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.4.1", + "@nomicfoundation/edr-darwin-x64": "0.4.1", + "@nomicfoundation/edr-linux-arm64-gnu": "0.4.1", + "@nomicfoundation/edr-linux-arm64-musl": "0.4.1", + "@nomicfoundation/edr-linux-x64-gnu": "0.4.1", + "@nomicfoundation/edr-linux-x64-musl": "0.4.1", + "@nomicfoundation/edr-win32-x64-msvc": "0.4.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.1.tgz", + "integrity": "sha512-XuiUUnWAVNw7JYv7nRqDWfpBm21HOxCRBQ8lQnRnmiets9Ss2X5Ul9mvBheIPh/D0wBzwJ8TRtsSrorpwE79cA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.1.tgz", + "integrity": "sha512-N1MfJqEX5ixaXlyyrHnaYxzwIT27Nc/jUgLI7ts4/9kRvPTvyZRYmXS1ciKhmUFr/WvFckTCix2RJbZoGGtX7g==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.1.tgz", + "integrity": "sha512-bSPOfmcFjJwDgWOV5kgZHeqg2OWu1cINrHSGjig0aVHehjcoX4Sgayrj6fyAxcOV5NQKA6WcyTFll6NrCxzWRA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.1.tgz", + "integrity": "sha512-F/+DgOdeBFQDrk+SX4aFffJFBgJfd75ZtE2mjcWNAh/qWiS7NfUxdQX/5OvNo/H6EY4a+3bZH6Bgzqg4mEWvMw==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.1.tgz", + "integrity": "sha512-POHhTWczIXCPhzKtY0Vt/l+VCqqCx5gNR5ErwSrNnLz/arfQobZFAU+nc61BX3Jch82TW8b3AbfGI73Kh7gO0w==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.1.tgz", + "integrity": "sha512-uu8oNp4Ozg3H1x1We0FF+rwXfFiAvsOm5GQ+OBx9YYOXnfDPWqguQfGIkhrti9GD0iYhfQ/WOG5wvp0IzzgGSg==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.1.tgz", + "integrity": "sha512-PaZHFw455z89ZiKYNTnKu+/TiVZVRI+mRJsbRTe2N0VlYfUBS1o2gdXBM12oP1t198HR7xQwEPPAslTFxGBqHA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", + "dependencies": { + "@nomicfoundation/ethereumjs-util": "9.0.4" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.7.tgz", + "integrity": "sha512-RQfsiTwdf0SP+DtuNYvm4921X6VirCQq0Xyh+mnuGlTwEFSPZ/o27oQC+l+3Y/l48DDU7+ZcYBR+Fp+Rp94LfQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "chai": "^4.2.0", + "ethers": "^6.1.0", + "hardhat": "^2.9.4" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz", + "integrity": "sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==", + "dependencies": { + "debug": "^4.1.1", + "lodash.isequal": "^4.5.0" + }, + "peerDependencies": { + "ethers": "^6.1.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.5.tgz", + "integrity": "sha512-Y5nhFXFqt4owA6Ooag8ZBFDF2RAZElMXViknVIsi3m45pbQimS50ti6FU8HxfRkDnBARa40CIn7UGV0hrelzDw==", + "dev": true, + "peer": true, + "dependencies": { + "@nomicfoundation/ignition-core": "^0.15.5", + "@nomicfoundation/ignition-ui": "^0.15.5", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.1", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition-ethers": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.5.tgz", + "integrity": "sha512-W6s1QN9CFxzSVZS6w9Jcj3WLaK32z2FP5MxNU2OKY1Fn9ZzLr+miXbUbWYuRHl6dxrrl6sE8cv33Cybv19pmCg==", + "dev": true, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "@nomicfoundation/hardhat-ignition": "^0.15.5", + "@nomicfoundation/ignition-core": "^0.15.5", + "ethers": "^6.7.0", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-network-helpers": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.11.tgz", + "integrity": "sha512-uGPL7QSKvxrHRU69dx8jzoBvuztlLCtyFsbgfXIwIjnO3dqZRz2GNMHJoO3C3dIiUNM6jdNF4AUnoQKDscdYrA==", + "dev": true, + "peer": true, + "dependencies": { + "ethereumjs-util": "^7.1.4" + }, + "peerDependencies": { + "hardhat": "^2.9.5" + } + }, + "node_modules/@nomicfoundation/hardhat-toolbox": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", + "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", + "dev": true, + "peerDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", + "@types/chai": "^4.2.0", + "@types/mocha": ">=9.1.0", + "@types/node": ">=18.0.0", + "chai": "^4.2.0", + "ethers": "^6.4.0", + "hardhat": "^2.11.0", + "hardhat-gas-reporter": "^1.0.8", + "solidity-coverage": "^0.8.1", + "ts-node": ">=8.0.0", + "typechain": "^8.3.0", + "typescript": ">=4.5.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.8.tgz", + "integrity": "sha512-x/OYya7A2Kcz+3W/J78dyDHxr0ezU23DKTrRKfy5wDPCnePqnr79vm8EXqX3gYps6IjPBYyGPZ9K6E5BnrWx5Q==", + "dev": true, + "peer": true, + "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", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/ignition-core": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.5.tgz", + "integrity": "sha512-FgvuoIXhakRSP524JzNQ4BviyzBBKpsFaOWubPZ4XACLT4/7vGqlJ/7DIn0D2NL2anQ2qs98/BNBY9WccXUX1Q==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "cbor": "^9.0.0", + "debug": "^4.3.2", + "ethers": "^6.7.0", + "fs-extra": "^10.0.0", + "immer": "10.0.2", + "lodash": "4.17.21", + "ndjson": "2.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@nomicfoundation/ignition-ui": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.5.tgz", + "integrity": "sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==", + "dev": true, + "peer": true + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", + "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", + "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", + "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", + "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", + "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", + "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", + "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", + "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==" + }, + "node_modules/@scure/base": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", + "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", + "dev": true, + "peer": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true, + "peer": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true, + "peer": true + }, + "node_modules/@typechain/ethers-v6": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", + "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "ethers": "6.x", + "typechain": "^8.3.2", + "typescript": ">=4.7.0" + } + }, + "node_modules/@typechain/hardhat": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-9.1.0.tgz", + "integrity": "sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==", + "dev": true, + "peer": true, + "dependencies": { + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "@typechain/ethers-v6": "^0.5.1", + "ethers": "^6.1.0", + "hardhat": "^2.9.9", + "typechain": "^8.3.2" + } + }, + "node_modules/@typechain/hardhat/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "peer": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "dev": true, + "peer": true + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "peer": true + }, + "node_modules/@types/mocha": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "dev": true, + "peer": true + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true, + "peer": true + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true, + "peer": true + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true, + "peer": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "devOptional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "devOptional": true, + "peer": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true, + "peer": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true, + "peer": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "peer": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "peer": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "peer": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dev": true, + "peer": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true, + "peer": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "peer": true + }, + "node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "peer": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", + "dev": true, + "peer": true, + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "peer": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "peer": true, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "peer": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "peer": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/command-line-usage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/command-line-usage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/command-line-usage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "peer": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true, + "peer": true + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", + "dev": true, + "peer": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "peer": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "dev": true, + "peer": true, + "dependencies": { + "heap": ">= 0.2.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "peer": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "peer": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "peer": true, + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "peer": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^10.2.0", + "req-cwd": "^2.0.0", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz", + "integrity": "sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethers": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.1.tgz", + "integrity": "sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "peer": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "peer": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/ghost-testrpc/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ghost-testrpc/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ghost-testrpc/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "peer": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "peer": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hardhat": { + "version": "2.22.6", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.6.tgz", + "integrity": "sha512-abFEnd9QACwEtSvZZGSmzvw7N3zhQN1cDKz5SLHAupfG24qTHofCjqvD5kT5Wwsq5XOL0ON1Mq5rr4v0XX5ciw==", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/edr": "^0.4.1", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "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", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", + "dev": true, + "peer": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/hardhat/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/hardhat/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/hardhat/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/hardhat/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/hardhat/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true, + "peer": true + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "peer": true, + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true, + "peer": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "peer": true + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "peer": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "peer": true + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "peer": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "peer": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "peer": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "peer": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "peer": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "peer": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true, + "peer": true + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true, + "peer": true + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "peer": true + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "peer": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", + "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", + "dev": true, + "peer": true, + "dependencies": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.5", + "readable-stream": "^3.6.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "ndjson": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "peer": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "peer": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", + "dev": true, + "peer": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true, + "peer": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "peer": true + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dev": true, + "peer": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "peer": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "peer": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", + "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "peer": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "peer": true, + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", + "dev": true, + "peer": true, + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", + "dev": true, + "peer": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "dev": true, + "peer": true + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "peer": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "dev": true, + "peer": true, + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "peer": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/solc": { + "version": "0.8.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", + "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solidity-coverage": { + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.12.tgz", + "integrity": "sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.18.0", + "chalk": "^2.4.2", + "death": "^1.1.0", + "difflib": "^0.2.4", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.21", + "mocha": "^10.2.0", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.6" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "hardhat": "^2.11.0" + } + }, + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true, + "peer": true + }, + "node_modules/solidity-coverage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/solidity-coverage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/solidity-coverage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solidity-coverage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "peer": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stl-contracts": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/stl-contracts/-/stl-contracts-2.5.1.tgz", + "integrity": "sha512-fkIq5BPq2/MTkQEDgXRM5WtrpQXqar3lDtha7N446UoCvNWP2isKfcRJ0RKatyMegGvRK1yWugDbbR3OGZiGXg==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "dev": true, + "peer": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "peer": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "peer": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true, + "peer": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-command-line-args": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", + "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.0", + "string-format": "^2.0.0" + }, + "bin": { + "write-markdown": "dist/write-markdown.js" + } + }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typechain": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", + "dev": true, + "peer": true, + "dependencies": { + "@types/prettier": "^2.1.1", + "debug": "^4.3.1", + "fs-extra": "^7.0.0", + "glob": "7.1.7", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.3.1", + "ts-command-line-args": "^2.2.0", + "ts-essentials": "^7.0.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.3.0" + } + }, + "node_modules/typechain/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/typechain/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typechain/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typechain/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "peer": true + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "devOptional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uglify-js": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true, + "peer": true + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "peer": true + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "peer": true, + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/assets/erc-7738/package.json b/assets/erc-7738/package.json new file mode 100644 index 0000000000..ff5f4896e3 --- /dev/null +++ b/assets/erc-7738/package.json @@ -0,0 +1,24 @@ +{ + "name": "hardhat", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@openzeppelin/contracts": "^5.0.2", + "dotenv": "^16.4.5", + "ethers": "^6.13.1", + "hardhat": "^2.22.6", + "stl-contracts": "^2.5.1" + }, + "devDependencies": { + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", + "@nomicfoundation/hardhat-toolbox": "^5.0.0" + } +} diff --git a/assets/erc-7738/test/DecentralisedRegistry.test.ts b/assets/erc-7738/test/DecentralisedRegistry.test.ts new file mode 100644 index 0000000000..677f8b7deb --- /dev/null +++ b/assets/erc-7738/test/DecentralisedRegistry.test.ts @@ -0,0 +1,151 @@ +const { ethers } = require("hardhat"); + +import { expect } from "chai"; +import { + loadFixture, +} from "@nomicfoundation/hardhat-toolbox/network-helpers"; + +const scriptURI1: string = "https://scripttoken.net/script1"; +const scriptURI2: string = "https://scripttoken.net/script2"; +const scriptURI3: string = "https://scripttoken.net/script3"; +const scriptURI4: string = "https://scripttoken.net/script4"; +const origScriptURI: string = "https://scripttoken.net/script"; + +async function deployInitialFixture() { + // Contracts are deployed using the first signer/account by default + const [owner, otherAccount, otherAccount2, otherAccount3, otherAccount4] = await ethers.getSigners(); + + const StakingToken = (await ethers.getContractFactory("StakingToken")).connect( + owner + ); + const stakingToken = await StakingToken.deploy(); + await stakingToken.waitForDeployment(); + + //Deploy registry contract + const Registry = (await ethers.getContractFactory("DecentralisedRegistry")).connect( + otherAccount + ); + const registry = await Registry.deploy(); + await registry.waitForDeployment(); + + return { + owner, + otherAccount, + otherAccount2, + otherAccount3, + otherAccount4, + stakingToken, + registry, + }; +} + +describe("DecentralisedRegistry", function () { + + it("mint and set scriptURI with owner", async function () { + const { + owner, + otherAccount, + otherAccount2, + otherAccount3, + otherAccount4, + stakingToken, + registry + } = await loadFixture(deployInitialFixture); + + await expect(stakingToken.connect(owner).safeMint()) + .to.emit(stakingToken, "Transfer") + .withArgs(ethers.ZeroAddress, owner.address, 1); + + const scriptURI = [scriptURI1]; + const scriptURITest2 = [scriptURI2]; + const scriptURITest3 = [scriptURI3, scriptURI4]; + const origScript = [origScriptURI]; + + //set scriptURI + await registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI); + + //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); + + expect((await registry.scriptURI(stakingToken.target)).toString()).to.be.equal(scriptURI.toString()); + + //attempt to set Script URI with delegate account + await registry.connect(otherAccount).setScriptURI(stakingToken.target, scriptURITest2); + + //now dump the current full scriptURI + //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); + + await registry.connect(otherAccount3).setScriptURI(stakingToken.target, scriptURITest3); + + //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); + + //now owner writes, should come first + await registry.connect(owner).setScriptURI(stakingToken.target, origScript); + + let finalScriptURI = await registry.scriptURI(stakingToken.target); + + //console.log(`Current ScriptURI = ${finalScriptURI}`); + + //test first element + let firstScriptURI = finalScriptURI[0]; + + //ensure owner script is first in list + expect(firstScriptURI).to.equal(origScriptURI); + + //add another entry + await registry.connect(otherAccount4).setScriptURI(stakingToken.target, [scriptURI4, scriptURI1, scriptURI2]); + + //owner script should still be first + finalScriptURI = await registry.scriptURI(stakingToken.target); + firstScriptURI = finalScriptURI[0]; + expect(firstScriptURI).to.equal(origScriptURI); + + //attempt to write zero sized scriptURI + await expect(registry.connect(otherAccount4).setScriptURI(stakingToken.target, [])) + .to.revertedWith("> 0 entries required in scriptURIList"); + + //remove an entry + await registry.connect(otherAccount4).setScriptURI(stakingToken.target, [""]); + //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); + + //and another + await registry.connect(otherAccount3).setScriptURI(stakingToken.target, [""]); + //console.log(`Current ScriptURI = ${await registry.scriptURI(stakingToken.target)}`); + + //now add back + await registry.connect(otherAccount3).setScriptURI(stakingToken.target, [scriptURI4, scriptURI1, scriptURI2]); + finalScriptURI = await registry.scriptURI(stakingToken.target); + //console.log(`Current ScriptURI = ${finalScriptURI}`); + + //check final return, should be: + let correctFinal = [origScriptURI, scriptURI1, scriptURI2, scriptURI4, scriptURI1, scriptURI2, ""]; + expect((await registry.scriptURI(stakingToken.target)).toString()).to.be.equal(correctFinal.toString()); + + checkPageSize(2, correctFinal, registry, stakingToken); + checkPageSize(3, correctFinal, registry, stakingToken); + checkPageSize(1, correctFinal, registry, stakingToken); + checkPageSize(500, correctFinal, registry, stakingToken); + }); + + + async function checkPageSize(pageSize: number, correctFinal: string[], registry: any, stakingToken: any) { + const totalPages = Math.ceil(correctFinal.length / pageSize); + + for (let page = 1; page <= totalPages; page++) { + let start = (page - 1) * pageSize; + let expected = []; + + for (let j = 0; j < pageSize; j++) { + if (start + j < correctFinal.length) { + expected[j] = correctFinal[start + j]; + } else { + break; + } + } + + let contractReturn = await registry.scriptURI(stakingToken.target, page, pageSize); + //console.log(`Actual return = ${contractReturn} Expected = ${expected}`); + expect(contractReturn.toString()).to.be.equal(expected.toString()); + } + } + +}) \ No newline at end of file diff --git a/assets/erc-7738/test/PermissionedRegistry.test.ts b/assets/erc-7738/test/PermissionedRegistry.test.ts new file mode 100644 index 0000000000..d14c7adbe9 --- /dev/null +++ b/assets/erc-7738/test/PermissionedRegistry.test.ts @@ -0,0 +1,111 @@ +const { ethers } = require("hardhat"); + +import { expect } from "chai"; +import { + loadFixture, +} from "@nomicfoundation/hardhat-toolbox/network-helpers"; + +const scriptURI1: string = "https://scripttoken.net/script1"; + +async function deployInitialFixture() { + // Contracts are deployed using the first signer/account by default + const [owner, otherAccount, otherAccount2] = await ethers.getSigners(); + + const StakingToken = (await ethers.getContractFactory("StakingToken")).connect( + owner + ); + const stakingToken = await StakingToken.deploy(); + await stakingToken.waitForDeployment(); + + //Deploy registry contract + const Registry = (await ethers.getContractFactory("DecentralisedRegistryPermissioned")).connect( + otherAccount + ); + const registry = await Registry.deploy(); + await registry.waitForDeployment(); + + return { + owner, + otherAccount, + otherAccount2, + stakingToken, + registry, + }; +} + +describe("Decentralised Permissioned Registry", function () { + + it("mint and set scriptURI with owner", async function () { + const { + owner, + otherAccount, + otherAccount2, + stakingToken, + registry + } = await loadFixture(deployInitialFixture); + + await expect(stakingToken.connect(owner).safeMint()) + .to.emit(stakingToken, "Transfer") + .withArgs(ethers.ZeroAddress, owner.address, 1); + + //initially register with otherAccount + await registry.connect(otherAccount).registerOwner(stakingToken.target); + + //owner can override + await registry.connect(owner).registerOwner(stakingToken.target); + + await expect(registry.connect(otherAccount).registerOwner(stakingToken.target)) + .to.revertedWith("Not authorized"); + + const scriptURI = [scriptURI1]; + + //set scriptURI + await expect(registry.connect(otherAccount).setScriptURI(stakingToken.target, scriptURI)) + .to.revertedWith("Not authorized"); + await expect(registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI)) + .to.revertedWith("Not authorized"); + + await registry.connect(owner).setScriptURI(stakingToken.target, scriptURI); + + expect((await registry.scriptURI(stakingToken.target)).toString()).to.be.equal(scriptURI.toString()); + + //add delegate + await expect(registry.connect(otherAccount).addDelegateSigner(stakingToken.target, otherAccount2)) + .to.revertedWith("Contract Owner only"); + + await registry.connect(owner).addDelegateSigner(stakingToken.target, otherAccount2); + + //attempt to set Script URI with delegate account + await registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI); + + // Verify script signing operation. + // Assume that a process has come back from evaluating the address of a TokenScript and needs to verify if the + // key is allowed to validate the contract + let ecRecoverSigningKey = otherAccount2.address; + + expect((await registry.isDelegateOrOwner(stakingToken.target, otherAccount.address))) + .to.be.equal(false); + + expect((await registry.isDelegateOrOwner(stakingToken.target, ecRecoverSigningKey))) + .to.be.equal(true); + + expect((await registry.isDelegateOrOwner(stakingToken.target, owner.address))) + .to.be.equal(true); + + // revoke + await expect(registry.connect(otherAccount2).revokeDelegateSigner(stakingToken.target, otherAccount2)) + .to.revertedWith("Contract Owner only"); + + await registry.connect(owner).revokeDelegateSigner(stakingToken.target, otherAccount2); + + await expect(registry.connect(otherAccount2).setScriptURI(stakingToken.target, scriptURI)) + .to.revertedWith("Not authorized"); + + expect((await registry.isDelegateOrOwner(stakingToken.target, ecRecoverSigningKey))) + .to.be.equal(false); + + expect((await registry.isDelegateOrOwner(stakingToken.target, owner.address))) + .to.be.equal(true); + }); + +}) \ No newline at end of file diff --git a/assets/erc-7738/tsconfig.json b/assets/erc-7738/tsconfig.json new file mode 100644 index 0000000000..574e785c71 --- /dev/null +++ b/assets/erc-7738/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } +} From def486b1ede283f6166f6b9a83200cbd05e5089e Mon Sep 17 00:00:00 2001 From: Lukas <36800180+lukasrosario@users.noreply.github.com> Date: Mon, 5 Aug 2024 03:07:47 -0400 Subject: [PATCH 20/79] Update ERC-7682: Add assets Merged by EIP-Bot. --- ERCS/erc-7682.md | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/ERCS/erc-7682.md b/ERCS/erc-7682.md index a210c89dce..226aad6b19 100644 --- a/ERCS/erc-7682.md +++ b/ERCS/erc-7682.md @@ -1,7 +1,7 @@ --- eip: 7682 title: Auxiliary Funds Capability -description: A way for wallets to indicate to apps that they have access to additional funds +description: A capability allowing wallets to indicate that they have access to additional funds. author: Lukas Rosario (@lukasrosario), Wilson Cusack (@wilsoncusack) discussions-to: https://ethereum-magicians.org/t/erc-7682-auxiliary-funds-capability/19599 status: Draft @@ -15,6 +15,11 @@ requires: 5792 An [EIP-5792](./eip-5792.md) compliant capability that allows wallets to indicate to apps that they have access to funds beyond those that can be accounted for by looking up balances onchain given the wallet's address. +A wallet's ability to access auxiliary funds is communicated to apps as part of its response to an [EIP-5792](./eip-5792.md) `wallet_getCapabilities` request. The following standard does not specify the source of these auxiliary funds, but some examples are: + +- Funds from offchain sources that can be onramped and used just-in-time +- Wallets that manage many accounts, where assets across those accounts can be transfered to the required account before submitting a transaction requested by an app + ## Motivation Many applications check users' balances before letting them complete some action. For example, if a user wants to swap some amount of tokens on a dex, the dex will commonly block the user from doing so if it sees that the user does not have that amount of tokens at their address. However, more advanced wallets have features that let users access funds from other sources. Wallets need a way to tell apps that they have access to additional funds so that users using these more advanced wallets are not blocked by balance checks. @@ -25,13 +30,20 @@ One new [EIP-5792](./eip-5792.md) wallet capability is defined. ### Wallet Implementation -To conform to this specification, wallets that wish to indicate that they have access to auxiliary funds MUST respond to `wallet_getCapabilities` calls with an `auxiliaryFunds` object with a `supported` field set to `true` for each chain they have access to auxiliary funds on. This specification does not put any constraints on the source of the auxiliary funds. +To conform to this specification, wallets that wish to indicate that they have access to auxiliary funds MUST, for each chain they have access to auxiliary funds on, respond to `wallet_getCapabilities` calls with an `auxiliaryFunds` object with a `supported` field set to `true`. + +Wallets may also optionally specify which assets they have additional access to with an `assets` field, which maps to an array of addresses representing the assets the wallet might have additional access to. If a wallet does not respond with this optional array of assets, the application SHOULD assume the wallet has additional access to any asset. + +This specification does not put any constraints on the source of the auxiliary funds. + +In this specification, a chain's native asset (e.g. Ether on Ethereum) MUST be represented by "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" as specified by [EIP-7528](./eip-7528). #### `wallet_getCapabilities` Response Specification ```typescript type AuxiliaryFundsCapability = { supported: boolean; + assets?: `0x${string}`[]; } ``` @@ -41,12 +53,20 @@ type AuxiliaryFundsCapability = { { "0x2105": { "auxiliaryFunds": { - "supported": true - }, + "supported": true, + "assets": [ + "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" + ] + } }, "0x14A34": { "auxiliaryFunds": { - "supported": true + "supported": true, + "assets": [ + "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "0x036CbD53842c5426634e7929541eC2318f3dCF7e" + ] } } } @@ -66,10 +86,6 @@ An alternative we considered is defining a way for apps to fetch available auxil The shape of this capability allows for a more advanced extension if apps feel more functionality is needed. -#### Auxiliary Funds per Asset - -We could also specify auxiliary funds support per asset. We decided against this because this list could get quite large if a wallet has auxiliary funds supports for many assets, and a single boolean should be enough for apps to not block users from taking actions. - ## Security Considerations Apps MUST NOT make any assumptions about the source of auxiliary funds. Apps' smart contracts should still, as they would today, make appropriate balance checks onchain when processing a transaction. From f899c81ec706b052a8c93cc421cda6710f0e881a Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Thu, 8 Aug 2024 13:11:06 +0200 Subject: [PATCH 21/79] Website: Reverting change tradeId to tradeData for termination. Merged by EIP-Bot. --- ERCS/erc-6123.md | 47 +++++++++++++------- assets/erc-6123/contracts/ISDC.sol | 30 +++++++------ assets/erc-6123/contracts/SDCSingleTrade.sol | 11 +++-- assets/erc-6123/package.json | 2 +- assets/erc-6123/test/SDCTests.js | 20 ++++++--- 5 files changed, 71 insertions(+), 39 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index de138cbe3b..0c9332eab3 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -65,9 +65,12 @@ The following methods specify a Smart Derivative Contract's trade initiation and A party can initiate a trade by providing the party address to trade with, trade data, trade position, payment amount for the trade and initial settlement data. Only registered counterparties are allowed to use that function. ```solidity -function inceptTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; +function inceptTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external returns (string memory); ``` +The position and the paymentAmount are viewed from the incepter. +The function will return a generated unique `tradeId`. The trade id will also be emitted by an event. + #### Trade Initiation Phase: `confirmTrade` A counterparty can confirm a trade by providing its trade specification data, which then gets matched against the data stored from `inceptTrade` call. @@ -76,6 +79,8 @@ A counterparty can confirm a trade by providing its trade specification data, wh function confirmTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; ``` +Here, the position and the paymentAmount is viewed from the confimer (opposite sign compared to the call to `inceptTrade`). + #### Trade Initiation Phase: `cancelTrade` The counterparty that called `inceptTrade` has the option to cancel the trade, e.g., in the case where the trade is not confirmed in a timely manner. @@ -109,7 +114,7 @@ This might result in a termination or start of the next settlement phase, depend The transactionData is emitted as part of the corresponding event: `TradeSettled` or `TradeTerminated` ```solidity -function afterTransfer(bool success, uint256 transactionData) external; +function afterTransfer(bool success, string memory transactionData) external; ``` @@ -162,7 +167,7 @@ event TradeConfirmed(address confirmer, string tradeId); Emitted on trade cancellation - method 'cancelTrade' ```solidity -event TradeCanceled(address confirmer, string tradeId); +event TradeCanceled(address initiator, string tradeId); ``` #### TradeActivated @@ -173,12 +178,13 @@ Emitted when a Trade is activated event TradeActivated(string tradeId); ``` + ### SettlementRequested Emitted when a settlement is requested. May trigger the settlement phase. ```solidity -event SettlementRequested(address initiator, string tradeId, string lastSettlementData); +event SettlementRequested(address initiator, string tradeData, string lastSettlementData); ``` ### SettlementEvaluated @@ -186,15 +192,33 @@ event SettlementRequested(address initiator, string tradeId, string lastSettleme Emitted when the settlement phase is started. ```solidity -event SettlementEvaluated(); +event SettlementEvaluated(address initiator, int256 settlementAmount, string settlementData); +``` + +### SettlementTransferred + +Emitted when the settlement succeeded. + +```solidity +event SettlementTransferred(string transactionData); ``` + +### SettlementFailed + +Emitted when the settlement failed. + +```solidity +event SettlementFailed(string transactionData); +``` + + #### TradeTerminationRequest Emitted when termination request is initiated by a counterparty ```solidity -event TradeTerminationRequest(address cpAddress, string tradeId, string terminationTerms); +event TradeTerminationRequest(address initiator, string tradeId, int256 terminationPayment, string terminationTerms); ``` #### TradeTerminationConfirmed @@ -202,7 +226,7 @@ event TradeTerminationRequest(address cpAddress, string tradeId, string terminat Emitted when termination request is confirmed by a counterparty ```solidity -event TradeTerminationConfirmed(address cpAddress, string tradeId, string terminationTerms); +event TradeTerminationConfirmed(address confirmer, string tradeId, int256 terminationPayment, string terminationTerms); ``` #### TradeTerminationCanceled @@ -210,7 +234,7 @@ event TradeTerminationConfirmed(address cpAddress, string tradeId, string termin Emitted when termination request is canceled by the requesting counterparty ```solidity -event TradeTerminationCanceled(address cpAddress, string tradeId, string terminationTerms); +event TradeTerminationCanceled(address initiator, string tradeId, string terminationTerms); ``` #### TradeTerminated @@ -221,13 +245,6 @@ Emitted when trade is terminated event TradeTerminated(string cause); ``` -#### ProcessHalted - -Emitted when trade processing stops. - -```solidity -event ProcessHalted(); -``` ## Rationale diff --git a/assets/erc-6123/contracts/ISDC.sol b/assets/erc-6123/contracts/ISDC.sol index dddc9bc172..1a2feb6c27 100644 --- a/assets/erc-6123/contracts/ISDC.sol +++ b/assets/erc-6123/contracts/ISDC.sol @@ -140,27 +140,29 @@ interface ISDC { /** * @dev Emitted when a counterparty proactively requests an early termination of the underlying trade - * @param cpAddress the address of the requesting party + * @param initiator the address of the requesting party + * @param terminationPayment an agreed termination amount (viewed from the requester) * @param tradeId the trade identifier which is supposed to be terminated * @param terminationTerms termination terms */ - event TradeTerminationRequest(address cpAddress, string tradeId, int256 terminationPayment, string terminationTerms); + event TradeTerminationRequest(address initiator, string tradeId, int256 terminationPayment, string terminationTerms); /** * @dev Emitted when early termination request is confirmed by the opposite party - * @param cpAddress the party which confirms the trade termination + * @param confirmer the party which confirms the trade termination * @param tradeId the trade identifier which is supposed to be terminated + * @param terminationPayment an agreed termination amount (viewed from the confirmer, negative of the value provided by the requester) * @param terminationTerms termination terms */ - event TradeTerminationConfirmed(address cpAddress, string tradeId, int256 terminationPayment, string terminationTerms); + event TradeTerminationConfirmed(address confirmer, string tradeId, int256 terminationPayment, string terminationTerms); /** * @dev Emitted when a counterparty cancels its requests an early termination of the underlying trade - * @param cpAddress the address of the requesting party + * @param initiator the address of the requesting party * @param tradeId the trade identifier which is supposed to be terminated * @param terminationTerms termination terms */ - event TradeTerminationCanceled(address cpAddress, string tradeId, string terminationTerms); + event TradeTerminationCanceled(address initiator, string tradeId, string terminationTerms); /*------------------------------------------- FUNCTIONALITY ---------------------------------------------------------------------------------------*/ @@ -174,8 +176,9 @@ interface ISDC { * @param position is the position the inceptor has in that trade * @param paymentAmount is the payment amount which can be positive or negative (viewed from the inceptor) * @param initialSettlementData the initial settlement data (e.g. initial market data at which trade was incepted) + * @return the tradeId uniquely determining this trade. */ - function inceptTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external; + function inceptTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external returns (string memory); /** * @notice Performs a matching of provided trade data and settlement data of a previous trade inception @@ -229,26 +232,27 @@ interface ISDC { /** * @notice Called from a counterparty to request a mutual termination * @dev emits a {TradeTerminationRequest} - * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param tradeId the trade identifier which is supposed to be terminated * @param terminationPayment an agreed termination amount (viewed from the requester) * @param terminationTerms the termination terms to be stored on chain. */ - function requestTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; + function requestTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; /** * @notice Called from a party to confirm an incepted termination, which might trigger a final settlement before trade gets closed * @dev emits a {TradeTerminationConfirmed} - * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param tradeId the trade identifier which is supposed to be terminated * @param terminationPayment an agreed termination amount (viewed from the confirmer, negative of the value provided by the requester) * @param terminationTerms the termination terms to be stored on chain. */ - function confirmTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; + function confirmTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; /** * @notice Called from a party to confirm an incepted termination, which might trigger a final settlement before trade gets closed * @dev emits a {TradeTerminationCanceled} - * @param tradeData a description of the trade specification e.g. in xml format, suggested structure - see assets/eip-6123/doc/sample-tradedata-filestructure.xml + * @param tradeId the trade identifier which is supposed to be terminated + * @param terminationPayment an agreed termination amount (viewed from the requester) * @param terminationTerms the termination terms */ - function cancelTradeTermination(string memory tradeData, int256 terminationPayment, string memory terminationTerms) external; + function cancelTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; } diff --git a/assets/erc-6123/contracts/SDCSingleTrade.sol b/assets/erc-6123/contracts/SDCSingleTrade.sol index c6dc890ae3..6c66929650 100644 --- a/assets/erc-6123/contracts/SDCSingleTrade.sol +++ b/assets/erc-6123/contracts/SDCSingleTrade.sol @@ -133,7 +133,7 @@ abstract contract SDCSingleTrade is ISDC { * emits a TradeIncepted * can be called only when TradeState = Incepted */ - function inceptTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external override onlyCounterparty onlyWhenTradeInactive { + function inceptTrade(address _withParty, string memory _tradeData, int _position, int256 _paymentAmount, string memory _initialSettlementData) external override onlyCounterparty onlyWhenTradeInactive returns (string memory) { require(msg.sender != _withParty, "Calling party cannot be the same as withParty"); require(_position == 1 || _position == -1, "Position can only be +1 or -1"); tradeState = TradeState.Incepted; // Set TradeState to Incepted @@ -144,6 +144,7 @@ abstract contract SDCSingleTrade is ISDC { tradeID = Strings.toString(transactionHash); tradeData = _tradeData; // Set trade data to enable querying already in inception state emit TradeIncepted(msg.sender, _withParty, tradeID, _tradeData, _position, _paymentAmount, _initialSettlementData); + return tradeID; } /* @@ -189,8 +190,7 @@ abstract contract SDCSingleTrade is ISDC { require(keccak256(abi.encodePacked(tradeID)) == keccak256(abi.encodePacked(_tradeId)), "Trade ID mismatch"); uint256 hash = uint256(keccak256(abi.encode(_tradeId, "terminate", _terminationPayment, terminationTerms))); pendingRequests[hash] = msg.sender; - terminationPayment = _terminationPayment; // termination payment will be provided in view of receiving party - emit TradeTerminationRequest(msg.sender, _tradeId, terminationPayment, terminationTerms); + emit TradeTerminationRequest(msg.sender, _tradeId, _terminationPayment, terminationTerms); } /* @@ -203,7 +203,10 @@ abstract contract SDCSingleTrade is ISDC { uint256 hashConfirm = uint256(keccak256(abi.encode(_tradeId, "terminate", -_terminationPayment, terminationTerms))); require(pendingRequests[hashConfirm] == pendingRequestParty, "Confirmation of termination failed due to wrong party or missing request"); delete pendingRequests[hashConfirm]; - emit TradeTerminationConfirmed(msg.sender, _tradeId, terminationPayment, terminationTerms); + + terminationPayment = msg.sender == receivingParty ? _terminationPayment : -_terminationPayment; // termination payment will be provided in view of receiving party + + emit TradeTerminationConfirmed(msg.sender, _tradeId, _terminationPayment, terminationTerms); /* Trigger Termination Payment Amount */ address payerAddress = terminationPayment > 0 ? otherParty(receivingParty) : receivingParty; uint256 absPaymentAmount = uint256(abs(_terminationPayment)); diff --git a/assets/erc-6123/package.json b/assets/erc-6123/package.json index 19e85871df..2286d3af93 100644 --- a/assets/erc-6123/package.json +++ b/assets/erc-6123/package.json @@ -1,6 +1,6 @@ { "name": "@finmath.net/sdc", - "version": "0.4.0", + "version": "0.4.2", "description": "Solidity Smart Derivative Contracts", "author": "Christian Fries, Peter Kohl-Landgraf, Alexandros Korpis", "license": "ISC", diff --git a/assets/erc-6123/test/SDCTests.js b/assets/erc-6123/test/SDCTests.js index 6351c12b47..22e39646d8 100644 --- a/assets/erc-6123/test/SDCTests.js +++ b/assets/erc-6123/test/SDCTests.js @@ -208,34 +208,42 @@ describe("Livecycle Unit-Tests for SDC Plege Balance", () => { await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + // Note: position = 1 => counterparty1 is the receivingParty const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); const receipt = await incept_call.wait(); const event = receipt.events.find(event => event.event === 'TradeIncepted'); const trade_id = event.args[2]; const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); + + // Note: terminationPayment is considered to be viewed from the requester here. const terminate_call = await sdc.connect(counterparty2).requestTradeTermination(trade_id, -terminationPayment, "terminationTerms"); + // Note: terminationPayment is considered to be viewed from the confirmer here. const confirm_terminate_call = await sdc.connect(counterparty1).confirmTradeTermination(trade_id, +terminationPayment, "terminationTerms"); + let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); - await expect(cp1_balance).equal(initialLiquidityBalance-terminationPayment); - await expect(cp2_balance).equal(initialLiquidityBalance+terminationPayment); + await expect(cp1_balance).equal(initialLiquidityBalance+terminationPayment); + await expect(cp2_balance).equal(initialLiquidityBalance-terminationPayment); }); + it("9b. CP1 is Receiving Party, Trade-Termination is incepted by CP1 which pays the termination payment to CP2", async () => { let token = await ERC20Factory.deploy(); await token.connect(counterparty1).mint(counterparty1.address,initialLiquidityBalance); await token.connect(counterparty2).mint(counterparty2.address,initialLiquidityBalance); let sdc = await SDCFactory.deploy(counterparty1.address, counterparty2.address,token.address,marginBufferAmount,terminationFee); + // Note: position = 1 => counterparty1 is the receivingParty const incept_call = await sdc.connect(counterparty1).inceptTrade(counterparty2.address, trade_data, 1, 0, "initialMarketData"); const receipt = await incept_call.wait(); const event = receipt.events.find(event => event.event === 'TradeIncepted'); const trade_id = event.args[2]; const confirm_call = await sdc.connect(counterparty2).confirmTrade(counterparty1.address, trade_data, -1, 0, "initialMarketData"); - const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, -terminationPayment, "terminationTerms"); - const confirm_terminate_call = await sdc.connect(counterparty2).confirmTradeTermination(trade_id, +terminationPayment, "terminationTerms"); + // Note: terminationPayment is considered to be viewed from the requester here. + const terminate_call = await sdc.connect(counterparty1).requestTradeTermination(trade_id, terminationPayment, "terminationTerms"); + const confirm_terminate_call = await sdc.connect(counterparty2).confirmTradeTermination(trade_id, -terminationPayment, "terminationTerms"); let cp1_balance = await token.connect(counterparty1).balanceOf(counterparty1.address); let cp2_balance = await token.connect(counterparty1).balanceOf(counterparty2.address); - await expect(cp1_balance).equal(initialLiquidityBalance-terminationPayment); - await expect(cp2_balance).equal(initialLiquidityBalance+terminationPayment); + await expect(cp1_balance).equal(initialLiquidityBalance+terminationPayment); + await expect(cp2_balance).equal(initialLiquidityBalance-terminationPayment); }); it("10. Successful Inception with Upfront transferred from CP2 to CP1 + successful settlement transferred from CP1 to CP2", async () => { From 85eb202a8c05bc373f0583cb9eaff9237ff69b65 Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Thu, 8 Aug 2024 13:26:13 +0200 Subject: [PATCH 22/79] Update ERC-6123: Minor fix to headlines (added subsection). Merged by EIP-Bot. --- ERCS/erc-6123.md | 56 +++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index 0c9332eab3..e58ec6f2e1 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -117,7 +117,6 @@ The transactionData is emitted as part of the corresponding event: `TradeSettled function afterTransfer(bool success, string memory transactionData) external; ``` - #### Trade Termination: `requestTermination` Allows an eligible party to request a mutual termination of the trade with the correspondig `tradeId` with a termination amount she is willing to pay and provide further termination terms (e.g. an XML) @@ -142,6 +141,7 @@ The party that initiated `requestTradeTermination` has the option to withdraw th function cancelTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external; ``` + ### Trade Events The following events are emitted during an SDC Trade life-cycle. @@ -178,71 +178,73 @@ Emitted when a Trade is activated event TradeActivated(string tradeId); ``` +#### TradeTerminationRequest -### SettlementRequested - -Emitted when a settlement is requested. May trigger the settlement phase. +Emitted when termination request is initiated by a counterparty ```solidity -event SettlementRequested(address initiator, string tradeData, string lastSettlementData); +event TradeTerminationRequest(address initiator, string tradeId, int256 terminationPayment, string terminationTerms); ``` -### SettlementEvaluated +#### TradeTerminationConfirmed -Emitted when the settlement phase is started. +Emitted when termination request is confirmed by a counterparty ```solidity -event SettlementEvaluated(address initiator, int256 settlementAmount, string settlementData); +event TradeTerminationConfirmed(address confirmer, string tradeId, int256 terminationPayment, string terminationTerms); ``` -### SettlementTransferred +#### TradeTerminationCanceled -Emitted when the settlement succeeded. +Emitted when termination request is canceled by the requesting counterparty ```solidity -event SettlementTransferred(string transactionData); +event TradeTerminationCanceled(address initiator, string tradeId, string terminationTerms); ``` +#### TradeTerminated -### SettlementFailed - -Emitted when the settlement failed. +Emitted when trade is terminated ```solidity -event SettlementFailed(string transactionData); +event TradeTerminated(string cause); ``` -#### TradeTerminationRequest +### Settlement Events -Emitted when termination request is initiated by a counterparty +The following events are emitted during the settlement phases. + +#### SettlementRequested + +Emitted when a settlement is requested. May trigger the settlement phase. ```solidity -event TradeTerminationRequest(address initiator, string tradeId, int256 terminationPayment, string terminationTerms); +event SettlementRequested(address initiator, string tradeData, string lastSettlementData); ``` -#### TradeTerminationConfirmed +#### SettlementEvaluated -Emitted when termination request is confirmed by a counterparty +Emitted when the settlement phase is started. ```solidity -event TradeTerminationConfirmed(address confirmer, string tradeId, int256 terminationPayment, string terminationTerms); +event SettlementEvaluated(address initiator, int256 settlementAmount, string settlementData); ``` -#### TradeTerminationCanceled +#### SettlementTransferred -Emitted when termination request is canceled by the requesting counterparty +Emitted when the settlement succeeded. ```solidity -event TradeTerminationCanceled(address initiator, string tradeId, string terminationTerms); +event SettlementTransferred(string transactionData); ``` -#### TradeTerminated +#### SettlementFailed -Emitted when trade is terminated +Emitted when the settlement failed. ```solidity -event TradeTerminated(string cause); +event SettlementFailed(string transactionData); ``` From d78b3128fba0a7ccb823ce413bdcd885e2c4ed8b Mon Sep 17 00:00:00 2001 From: Christian Fries Date: Thu, 8 Aug 2024 14:49:17 +0200 Subject: [PATCH 23/79] Update ERC-6123: Update Diagrams Merged by EIP-Bot. --- ERCS/erc-6123.md | 6 + assets/erc-6123/doc/sdc_trade_states.svg | 257 +++++++++++------------ assets/erc-6123/doc/sequence.puml | 35 +-- assets/erc-6123/doc/sequence.svg | 2 +- 4 files changed, 153 insertions(+), 147 deletions(-) diff --git a/ERCS/erc-6123.md b/ERCS/erc-6123.md index e58ec6f2e1..eeedbc2bb2 100644 --- a/ERCS/erc-6123.md +++ b/ERCS/erc-6123.md @@ -264,9 +264,15 @@ The interface design and reference implementation are based on the following con ![image info](../assets/eip-6123/doc/sdc_trade_states.svg) +The diagram shows the trade states of a single trade SDC as in `SDCSingleTrade.sol`. + ### Sequence diagram of reference implementation 'SDCPledgedBalance.sol' + ![image info](../assets/eip-6123/doc/sequence.svg) +The sequence diagram show the function calls that create the trade and stellement state transitions +and the emitted events. + ## Test Cases Life-cycle unit tests based on the sample implementation and usage of [ERC-20](./eip-20.md) token is provided. See file [test/SDCTests.js](../assets/eip-6123/test/SDCTests.js) diff --git a/assets/erc-6123/doc/sdc_trade_states.svg b/assets/erc-6123/doc/sdc_trade_states.svg index fb99c78fc4..31219ae7c5 100644 --- a/assets/erc-6123/doc/sdc_trade_states.svg +++ b/assets/erc-6123/doc/sdc_trade_states.svg @@ -1,9 +1,9 @@ - + + xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="11.6929in" height="8.26772in" + viewBox="0 0 841.89 595.276" xml:space="preserve" color-interpolation-filters="sRGB" class="st22"> @@ -19,22 +19,21 @@ .st5 {fill:#316176} .st6 {stroke:#316176;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} .st7 {fill:#ffffff;font-family:Calibri;font-size:1.00001em} - .st8 {fill:#aecedd;stroke:#85b6cc;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5;visibility:hidden} - .st9 {fill:#ffffff;stroke:#85b6cc;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} - .st10 {fill:#aecedd} - .st11 {stroke:#85b6cc;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} - .st12 {marker-end:url(#mrkr4-49);stroke:#9b9b9b;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} - .st13 {fill:#9b9b9b;fill-opacity:1;stroke:#9b9b9b;stroke-opacity:1;stroke-width:0.16556291390728} - .st14 {fill:#ffffff;stroke:none;stroke-linecap:butt;stroke-width:7.2} - .st15 {fill:#595959;font-family:Calibri;font-size:0.666664em} - .st16 {font-size:1em} - .st17 {fill:#316176;stroke:#316176;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} - .st18 {fill:#ffffff;stroke:none;stroke-linecap:butt} - .st19 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} - .st20 {marker-end:url(#mrkr4-49);stroke:#9b9b9b;stroke-dasharray:3.5,2.5;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} - .st21 {fill:none} - .st22 {stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} - .st23 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + .st8 {fill:#ffffff;font-family:Calibri;font-size:0.833336em} + .st9 {fill:#aecedd;stroke:#85b6cc;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5;visibility:hidden} + .st10 {fill:#ffffff;stroke:#85b6cc;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} + .st11 {fill:#aecedd} + .st12 {stroke:#85b6cc;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} + .st13 {marker-end:url(#mrkr4-49);stroke:#9b9b9b;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} + .st14 {fill:#9b9b9b;fill-opacity:1;stroke:#9b9b9b;stroke-opacity:1;stroke-width:0.16556291390728} + .st15 {fill:#ffffff;stroke:none;stroke-linecap:butt;stroke-width:7.2} + .st16 {fill:#595959;font-family:Calibri;font-size:0.666664em} + .st17 {font-size:1em} + .st18 {fill:#316176;stroke:#316176;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} + .st19 {fill:#ffffff;stroke:none;stroke-linecap:butt} + .st20 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} + .st21 {marker-end:url(#mrkr4-49);stroke:#9b9b9b;stroke-dasharray:3.5,2.5;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5} + .st22 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} ]]> @@ -42,7 +41,7 @@ - @@ -53,20 +52,20 @@ Zeichenblatt-1 + v:shadowOffsetY="-8.50394"/> - + Anfangszustand - Start + Inactive - + - Start - + Inactive + @@ -100,11 +99,11 @@ + class="st6"/> Incepted - + @@ -138,11 +137,11 @@ + class="st6"/> Confirmed - + @@ -153,34 +152,34 @@ Zusammengesetzter Zustand.408 - + - + Sheet.409 - Terminated - + InTermination + Sheet.410 - + - - + - - Terminated + + InTermination - + @@ -191,7 +190,7 @@ Zusammengesetzter Zustand.419 - + @@ -206,51 +205,51 @@ - + + L35.43 595.28 Z" class="st11"/> + class="st12"/> Cancelled - + Dynamischer Verbinder.304 tx: inceptTrade by Couterparty1 - - - tx: inceptTradeby Couterparty1 - + + + tx: inceptTradeby Couterparty1 + Dynamischer Verbinder.313 tx: confirmTrade by Counterparty2 - - - tx: confirmTradeby Counterparty2 - + + + tx: confirmTradeby Counterparty2 + Dynamischer Verbinder.66 tx: afterTransfer - - - tx: afterTransfer - + + + tx: afterTransfer + Zustand.71 - + Sheet.354 @@ -260,23 +259,23 @@ - + Valuation - + Auswahl.292 - + - + Zustand.336 - + Sheet.360 @@ -286,16 +285,16 @@ - + Settled - + Zustand.380 - + Sheet.381 @@ -305,64 +304,65 @@ - + inTransfer - + Dynamischer Verbinder.398 success - - - success - + + + success + Dynamischer Verbinder.399 tx: initiateSettlement - - - - tx: initiateSettlement - + + + + tx: initiateSettlement + Dynamischer Verbinder.401 Initiate Transfer of Margin Buffers to SDC Balance - - - Initiate Transfer of Margin Buffers to SDC Balance - + + + Initiate Transfer of Margin Buffers to SDC Balance + Dynamischer Verbinder tx: perfomSettlement Initiate Transfer of Settlement Amount - - - tx: perfomSettlementInitiate Transfer ofSettlement Amount - + + + tx: perfomSettlementInitiate Transfer ofSettlement Amount + Dynamischer Verbinder.411 fail - - - - fail - + + + + fail + Dynamischer Verbinder.412 - Transfer Open Settlement Amount from SDC Balance + Final Transfer either from Party‘s or SDC Balance - - - - Transfer Open Settlement Amount from SDC Balance - + + + + Final Transfereither from Party‘sor SDC Balance + Sheet.413 - + - + - + Endzustand - End + Terminated - + - End - + Terminated + Auswahl.415 - + - + Dynamischer Verbinder.417 - + - + Dynamischer Verbinder.418 - Mutuall terminated or Maturity + Mutual Termination - - - - Mutuall terminated or Maturity - + + + + Mutual Termination + Dynamischer Verbinder.422 OPT: cancelInception - - - OPT: cancelInception - - Dynamischer Verbinder.430 - fail - - - - - - fail + + + OPT: cancelInception diff --git a/assets/erc-6123/doc/sequence.puml b/assets/erc-6123/doc/sequence.puml index ea04005b0e..a240a31445 100644 --- a/assets/erc-6123/doc/sequence.puml +++ b/assets/erc-6123/doc/sequence.puml @@ -9,12 +9,9 @@ title SmartDerivativeContract with Settlement-Token and off-chain Valuation Serv participant SettlementToken - participant EventHandler participant ValuationService - - activate EventHandler activate SettlementToken activate ValuationService @@ -31,17 +28,23 @@ CP1 ->SDC: tx 'inceptTrade' SDC-->EventHandler: emit TradeIncepted == TradeState 'Incepted' == -CP2->SDC: tx 'confirmTrade' -SDC->SDC: validate tradedata -SDC-->EventHandler: emit TradeConfirmed + CP2->SDC: tx 'confirmTrade' + SDC->SDC: validate tradedata + + SDC-->EventHandler: emit TradeConfirmed == TradeState 'Confirmed' == -SDC ->SettlementToken: tx 'transferFrom' margin buffers and termination fees\nto SDC address for CP1 and CP2 -SDC->SettlementToken: tx 'transferFrom' optional Upfront Fee from Paying to Receiving Party + SDC -> SettlementToken: tx 'transferFrom' margin buffers and termination fees\nto SDC address for CP1 and CP2 + SDC -> SettlementToken: tx 'transferFrom' optional Upfront Fee from Paying to Receiving Party + == TradeState 'inTransfer' == -SettlementToken->SDC: callback tx 'afterSettlement' + + SettlementToken->SDC: callback tx 'afterTransfer' + + SDC-->EventHandler: emit TradeActivated + ==ProcessState 'Settled' == end @@ -52,25 +55,31 @@ loop Every Settlement CP1->SDC: tx: 'initiateSettlement' == TradeState 'Valuation' == -SDC-->EventHandler:emit ProcessSettlementRequest +SDC-->EventHandler:emit SettlementRequested EventHandler->ValuationService: request valuation data ValuationService->EventHandler: return valuation data EventHandler->SDC: callback: tx 'performSettlement' SDC->SDC:Caps Settlement Amount at Margin Buffer Level + +SDC-->EventHandler: emit SettlementEvaluated + SDC->SettlementToken: tx 'transferFrom' settlement amount from Paying Party to Receiving Party Balance == TradeState 'inTransfer' == -SDC-->EventHandler: emit AwaitingTransfer alt Transfer Check - SettlementToken->SDC: callback tx 'afterSettlement' + SettlementToken->SDC: callback tx 'afterTransfer' else success + SDC-->EventHandler: emit SettlementTransferred == TradeState 'Settled' == else fail + SDC-->EventHandler: emit SettlementFailed + SDC->SettlementToken: tx 'transfer' Settlement Amount from SDC Balance to Receiving Party SDC->SettlementToken: tx 'transfer' Termination Fee from SDC Balance to Receiving Party - SDC->SettlementToken: tx 'transfer' - Release remainigBalances to parties + SDC->SettlementToken: tx 'transfer' - Release remainigBalances to parties + SDC-->EventHandler: emit TradeTerminated == TradeState 'Terminated' == end diff --git a/assets/erc-6123/doc/sequence.svg b/assets/erc-6123/doc/sequence.svg index f7e877a984..99362b5977 100644 --- a/assets/erc-6123/doc/sequence.svg +++ b/assets/erc-6123/doc/sequence.svg @@ -1 +1 @@ -SmartDerivativeContract with Settlement-Token and off-chain Valuation ServiceCP1CP1CP2CP2SDCSDCSettlementTokenSettlementTokenEventHandlerEventHandlerValuationServiceValuationServiceInitialize Tradeallocate balancesallocate balancestx 'deploy' a SDC with token addresstx set 'allowance' for SDC addresstx set 'allowance' for SDC addresstx 'inceptTrade'emit TradeInceptedTradeState 'Incepted'tx 'confirmTrade'validate tradedataemit TradeConfirmedTradeState 'Confirmed'tx 'transferFrom' margin buffers and termination feesto SDC address for CP1 and CP2tx 'transferFrom' optional Upfront Fee from Paying to Receiving PartyTradeState 'inTransfer'callback tx 'afterSettlement'ProcessState 'Settled'loop[Every Settlement]tx: 'initiateSettlement'TradeState 'Valuation'emit ProcessSettlementRequestrequest valuation datareturn valuation datacallback: tx 'performSettlement'Caps Settlement Amount at Margin Buffer Leveltx 'transferFrom' settlement amount from Paying Party to Receiving Party BalanceTradeState 'inTransfer'emit AwaitingTransferalt[Transfer Check]callback tx 'afterSettlement'[success]TradeState 'Settled'[fail]tx 'transfer' Settlement Amount from SDC Balance to Receiving Partytx 'transfer' Termination Fee from SDC Balance to Receiving Partytx 'approve' - Unlock remaing Party BalancesTradeState 'Terminated' \ No newline at end of file +SmartDerivativeContract with Settlement-Token and off-chain Valuation ServiceCP1CP1CP2CP2SDCSDCSettlementTokenSettlementTokenEventHandlerEventHandlerValuationServiceValuationServiceInitialize Tradeallocate balancesallocate balancestx 'deploy' a SDC with token addresstx 'inceptTrade'emit TradeInceptedTradeState 'Incepted'tx 'confirmTrade'validate tradedataemit TradeConfirmedTradeState 'Confirmed'tx 'transferFrom' margin buffers and termination feesto SDC address for CP1 and CP2tx 'transferFrom' optional Upfront Fee from Paying to Receiving PartyTradeState 'inTransfer'callback tx 'afterTransfer'emit TradeActivatedProcessState 'Settled'loop[Every Settlement]tx: 'initiateSettlement'TradeState 'Valuation'emit SettlementRequestedrequest valuation datareturn valuation datacallback: tx 'performSettlement'Caps Settlement Amount at Margin Buffer Levelemit SettlementEvaluatedtx 'transferFrom' settlement amount from Paying Party to Receiving Party BalanceTradeState 'inTransfer'alt[Transfer Check]callback tx 'afterTransfer'[success]emit SettlementTransferredTradeState 'Settled'[fail]emit SettlementFailedtx 'transfer' Settlement Amount from SDC Balance to Receiving Partytx 'transfer' Termination Fee from SDC Balance to Receiving Partytx 'transfer' - Release remainigBalances to partiesemit TradeTerminatedTradeState 'Terminated' \ No newline at end of file From 5c95af494e667ba35102c1b3093c5d966f5c2264 Mon Sep 17 00:00:00 2001 From: Ko Fujimura Date: Sun, 11 Aug 2024 08:35:27 +0900 Subject: [PATCH 24/79] Update ERC-7303: Update erc-7303.md Merged by EIP-Bot. --- ERCS/erc-7303.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7303.md b/ERCS/erc-7303.md index ab2a23c5cb..109800737d 100644 --- a/ERCS/erc-7303.md +++ b/ERCS/erc-7303.md @@ -154,7 +154,7 @@ contract MyToken is ERC721, ERC7303 { _grantRoleByERC1155(BURNER_ROLE, 0x..., ...); } - function safeMint(address to, uint256 tokenId, string memory uri) + function safeMint(address to, uint256 tokenId) public onlyHasToken(MINTER_ROLE, msg.sender) { _safeMint(to, tokenId); From f9fdd106b92e5e3d4b7f8d8afbb8261fb61c5c1b Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 13 Aug 2024 12:50:30 +0200 Subject: [PATCH 25/79] Update ERC-7579: specify fallback authorization control Merged by EIP-Bot. --- ERCS/erc-7579.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ERCS/erc-7579.md b/ERCS/erc-7579.md index 199130bf71..02a467b8f6 100644 --- a/ERCS/erc-7579.md +++ b/ERCS/erc-7579.md @@ -54,8 +54,8 @@ To comply with this standard, smart accounts MUST implement the execution interf interface IExecution { /** * @dev Executes a transaction on behalf of the account. - * @param mode The encoded execution mode of the transaction. See ModeLib.sol for details - * @param executionCalldata The encoded execution call data + * @param mode The encoded execution mode of the transaction. + * @param executionCalldata The encoded execution call data. * * MUST ensure adequate authorization control: e.g. onlyEntryPointOrSelf if used with ERC-4337 * If a mode is requested that is not supported by the Account, it MUST revert @@ -65,8 +65,8 @@ interface IExecution { /** * @dev Executes a transaction on behalf of the account. * This function is intended to be called by Executor Modules - * @param mode The encoded execution mode of the transaction. See ModeLib.sol for details - * @param executionCalldata The encoded execution call data + * @param mode The encoded execution mode of the transaction. + * @param executionCalldata The encoded execution call data. * * MUST ensure adequate authorization control: i.e. onlyExecutorModule * If a mode is requested that is not supported by the Account, it MUST revert @@ -218,10 +218,10 @@ Smart accounts MAY implement a fallback function that forwards the call to a fal If the smart account has a fallback handler installed, it: -- MUST implement authorization control -- MUST use `call` to invoke the fallback handler +- MUST use `call` or `staticcall` to invoke the fallback handler - MUST utilize [ERC-2771](./eip-2771.md) to add the original `msg.sender` to the `calldata` sent to the fallback handler - MUST route to fallback handlers based on the function selector of the calldata +- MAY implement authorization control, which SHOULD be done via hooks #### ERC-165 @@ -305,7 +305,7 @@ Executors MUST implement the `IModule` interface and have module type id: `2`. Fallback handlers MUST implement the `IModule` interface and have module type id: `3`. -Fallback handlers that implement authorization control, MUST NOT rely on `msg.sender` for authorization control but MUST use ERC-2771 `_msgSender()` instead. +Fallback handlers MAY implement authorization control. Fallback handlers that do implement authorization control, MUST NOT rely on `msg.sender` for authorization control but MUST use ERC-2771 `_msgSender()` instead. #### Hooks From b7b790300906f1f19499504f8798ce32bb2235bf Mon Sep 17 00:00:00 2001 From: Lukas <36800180+lukasrosario@users.noreply.github.com> Date: Thu, 15 Aug 2024 01:30:36 -0400 Subject: [PATCH 26/79] Update ERC-7677: Move to Review Merged by EIP-Bot. --- ERCS/erc-7677.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7677.md b/ERCS/erc-7677.md index 528f0e279d..8f49665cb6 100644 --- a/ERCS/erc-7677.md +++ b/ERCS/erc-7677.md @@ -4,7 +4,7 @@ title: Paymaster Web Service Capability description: A way for apps to communicate with smart wallets about paymaster web services author: Lukas Rosario (@lukasrosario), Dror Tirosh (@drortirosh), Wilson Cusack (@wilsoncusack), Kristof Gazso (@kristofgazso), Hazim Jumali (@hazim-j) discussions-to: https://ethereum-magicians.org/t/erc-7677-paymaster-web-service-capability/19530 -status: Draft +status: Review type: Standards Track category: ERC created: 2024-04-03 From 9f7e122cf208f8cd21421dd038a72a1e7aa096e7 Mon Sep 17 00:00:00 2001 From: Dror Tirosh Date: Thu, 15 Aug 2024 14:52:59 +0300 Subject: [PATCH 27/79] Update ERC-4337: erc4337 updates Merged by EIP-Bot. --- ERCS/erc-4337.md | 93 ++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/ERCS/erc-4337.md b/ERCS/erc-4337.md index e4a26772cb..49aadfa97b 100644 --- a/ERCS/erc-4337.md +++ b/ERCS/erc-4337.md @@ -76,14 +76,14 @@ To avoid Ethereum consensus changes, we do not attempt to create new transaction | `paymasterData` | `bytes` | Data for paymaster (only if paymaster exists) | | `signature` | `bytes` | Data passed into the account to verify authorization | -Users send `UserOperation` objects to a dedicated user operation mempool. The are not concerned with the packed version. +Users send `UserOperation` objects to a dedicated user operation mempool. They are not concerned with the packed version. A specialized class of actors called **bundlers** (either block builders running special-purpose code, or users that can relay transactions to block builders eg. through a bundle marketplace such as Flashbots that can guarantee next-block-or-never inclusion) listen in on the user operation mempool, and create **bundle transactions**. A bundle transaction packages up multiple `UserOperation` objects into a single `handleOps` call to a pre-published global **entry point contract**. To prevent replay attacks (both cross-chain and multiple `EntryPoint` implementations), the `signature` should depend on `chainid` and the `EntryPoint` address. ### EntryPoint definition -When passed to on-chain contacts (the EntryPoint contract, and then to account and paymaster), a packed version of the above structure is used: +When passed to on-chain contacts (the EntryPoint contract, and then to the account and paymaster), a packed version of the above structure is used: | Field | Type | Description | |----------------------|-----------|------------------------------------------------------------------------| @@ -132,12 +132,12 @@ The `userOpHash` is a hash over the userOp (except signature), entryPoint and ch The account: * MUST validate the caller is a trusted EntryPoint -* If the account does not support signature aggregation, it MUST validate the signature is a valid signature of the `userOpHash`, and +* If the account does not support signature aggregation, it MUST validate that the signature is a valid signature of the `userOpHash`, and SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error MUST revert. -* MUST pay the entryPoint (caller) at least the "missingAccountFunds" (which might be zero, in case current account's deposit is high enough) +* MUST pay the entryPoint (caller) at least the "missingAccountFunds" (which might be zero, in case the current account's deposit is high enough) * The account MAY pay more than this minimum, to cover future transactions (it can always issue `withdrawTo` to retrieve it) * The return value MUST be packed of `authorizer`, `validUntil` and `validAfter` timestamps. - * authorizer - 0 for valid signature, 1 to mark signature failure. Otherwise, an address of an authorizer contract. This ERC defines "signature aggregator" as authorizer. + * authorizer - 0 for valid signature, 1 to mark signature failure. Otherwise, an address of an authorizer contract. This ERC defines a "signature aggregator" as an authorizer. * `validUntil` is 6-byte timestamp value, or zero for "infinite". The UserOp is valid only up to this time. * `validAfter` is 6-byte timestamp. The UserOp is valid only after this time. @@ -208,7 +208,7 @@ this bundler is supposed to track the `key` and `sequence` pair of the UserOpera In some cases, an account may need to have an "administrative" channel of operations running in parallel to normal operations. - In this case, the account may use specific `key` when calling methods on the account itself: + In this case, the account may use a specific `key` when calling methods on the account itself: ```solidity bytes4 sig = bytes4(userOp.callData[0 : 4]); @@ -224,7 +224,7 @@ this bundler is supposed to track the `key` and `sequence` pair of the UserOpera There are 2 separate entry point methods: `handleOps` and `handleAggregatedOps` -* `handleOps` handle userOps of accounts that don't require any signature aggregator. +* `handleOps` handles userOps of accounts that don't require any signature aggregator. * `handleAggregatedOps` can handle a batch that contains userOps of multiple aggregators (and also requests without any aggregator) * `handleAggregatedOps` performs the same logic below as `handleOps`, but it must transfer the correct aggregator to each userOp, and also must call `validateSignatures` on each aggregator before doing all the per-account validation. The entry point's `handleOps` function must perform the following steps (we first describe the simpler non-paymaster case). It must make two loops, the **verification loop** and the **execution loop**. In the verification loop, the `handleOps` call must perform the following steps for each `UserOperation`: @@ -279,7 +279,7 @@ enum PostOpMode { } ``` -The EntryPoint must implement the following API to let entities like paymasters to have a stake, and thus have more flexibility in their storage access (see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details.) +The EntryPoint must implement the following API to let entities like paymasters have a stake, and thus have more flexibility in their storage access (see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details.) ```solidity // add a stake to the calling entity @@ -295,7 +295,7 @@ function withdrawStake(address payable withdrawAddress) external The paymaster must also have a deposit, which the entry point will charge UserOperation costs from. The deposit (for paying gas fees) is separate from the stake (which is locked). -The EntryPoint must implement the following interface to allow paymasters (and optionally accounts) manage their deposit: +The EntryPoint must implement the following interface to allow paymasters (and optionally accounts) to manage their deposit: ```c++ // return the deposit of an account @@ -313,9 +313,9 @@ function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) ext When a client receives a `UserOperation`, it must first run some basic sanity checks, namely that: * Either the `sender` is an existing contract, or the `initCode` is not empty (but not both) -* If `initCode` is not empty, parse its first 20 bytes as a factory address. Record whether the factory is staked, in case the later simulation indicates that it needs to be. If the factory accesses global state, it must be staked - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details. +* If `initCode` is not empty, parse its first 20 bytes as a factory address. Record whether the factory is staked, in case the later simulation indicates that it needs to be. If the factory accesses the global state, it must be staked - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details. * The `verificationGasLimit` is sufficiently low (`<= MAX_VERIFICATION_GAS`) and the `preVerificationGas` is sufficiently high (enough to pay for the calldata gas cost of serializing the `UserOperation` plus `PRE_VERIFICATION_OVERHEAD_GAS`) -* The `paymasterAndData` is either empty, or start with the **paymaster** address, which is a contract that (i) currently has nonempty code on chain, (ii) has a sufficient deposit to pay for the UserOperation, and (iii) is not currently banned. During simulation, the paymaster's stake is also checked, depending on its storage usage - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details. +* The `paymasterAndData` is either empty, or starts with the **paymaster** address, which is a contract that (i) currently has nonempty code on chain, (ii) has a sufficient deposit to pay for the UserOperation, and (iii) is not currently banned. During simulation, the paymaster's stake is also checked, depending on its storage usage - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details. * The callgas is at least the cost of a `CALL` with non-zero value. * The `maxFeePerGas` and `maxPriorityFeePerGas` are above a configurable minimum value that the client is willing to accept. At the minimum, they are sufficiently high to be included with the current `block.basefee`. * The sender doesn't have another `UserOperation` already present in the pool (or it replaces an existing entry with the same sender and nonce, with a higher `maxPriorityFeePerGas` and an equally increased `maxFeePerGas`). Only one `UserOperation` per sender may be included in a single batch. A sender is exempt from this rule and may have multiple `UserOperations` in the pool and in a batch if it is staked (see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) below), but this exception is of limited use to normal accounts. @@ -340,12 +340,12 @@ interface IAggregator { * An account signifies it uses signature aggregation returning its address from `validateUserOp`. * During `simulateValidation`, this aggregator is returned to the bundler as part of the `aggregatorInfo` struct. -* The bundler should first accept the aggregator (aggregators must be staked. bundler should verify it is not throttle/banned) +* The bundler should first accept the aggregator (aggregators must be staked. bundler should verify it is not throttled/banned) * To accept the UserOp, the bundler must call **validateUserOpSignature()** to validate the userOp's signature. This method returned an alternate signature (usually empty) that should be used during bundling. * The bundler MUST call `validateUserOp` a second time on the account with the UserOperation using that returned signature, and make sure it returns the same value. * **aggregateSignatures()** must aggregate all UserOp signatures into a single value. -* Note that the above methods are helper method for the bundler. The bundler MAY use a native library to perform the same validation and aggregation logic. +* Note that the above methods are helper methods for the bundler. The bundler MAY use a native library to perform the same validation and aggregation logic. * **validateSignatures()** MUST validate the aggregated signature matches for all UserOperations in the array, and revert otherwise. This method is called on-chain by `handleOps()` @@ -353,11 +353,11 @@ interface IAggregator { #### Simulation Rationale -In order to add a UserOperation into the mempool (and later to add it into a bundle) we need to "simulate" its validation to make sure it is valid, and that it is capable of paying for its own execution. +To add a UserOperation into the mempool (and later to add it into a bundle) we need to "simulate" its validation to make sure it is valid, and that it pays for its own execution. In addition, we need to verify that the same will hold true when executed on-chain. For this purpose, a UserOperation is not allowed to access any information that might change between simulation and execution, such as current block time, number, hash etc. -In addition, a UserOperation is only allowed to access data related to this sender address: Multiple UserOperations should not access the same storage, so that it is impossible to invalidate a large number of UserOperations with a single state change. -There are 3 special contracts that interact with the account: the factory (initCode) that deploys the contract, the paymaster that can pay for the gas, and signature aggregator (described later) +In addition, a UserOperation is only allowed to access data related to this sender address: Multiple UserOperations should not access the same storage, so it is impossible to invalidate a large number of UserOperations with a single state change. +There are 3 special contracts that interact with the account: the factory (initCode) that deploys the contract, the paymaster that can pay for the gas, and a signature aggregator (described later) Each of these contracts is also restricted in its storage access, to make sure UserOperation validations are isolated. #### Simulation Specification: @@ -419,15 +419,15 @@ Either return value may contain a "validAfter" and "validUntil" timestamps, whic A node MAY drop a UserOperation if it expires too soon (e.g. wouldn't make it to the next block) by either the account or paymaster. If the `ValidationResult` includes `sigFail`, the client SHOULD drop the `UserOperation`. -In order to prevent DoS attack on bundlers, they must make sure the validation methods above pass the validation rules, which constraint their usage of opcodes and storage. +To prevent DoS attacks on bundlers, they must make sure the validation methods above pass the validation rules, which constrain their usage of opcodes and storage. For the complete procedure see [ERC-7562](./eip-7562.md) ### Alternative Mempools The simulation rules above are strict and prevent the ability of paymasters and signature aggregators to grief the system. -However, there might be use-cases where specific paymasters (and signature aggregators) can be validated +However, there might be use cases where specific paymasters (and signature aggregators) can be validated (through manual auditing) and verified that they cannot cause any problem, while still require relaxing of the opcode rules. -A bundler cannot simply "whitelist" request from a specific paymaster: if that paymaster is not accepted by all +A bundler cannot simply "whitelist" a request from a specific paymaster: if that paymaster is not accepted by all bundlers, then its support will be sporadic at best. Instead, we introduce the term "alternate mempool": a modified validation rules, and procedure of propagating them to other bundlers. @@ -435,7 +435,7 @@ The procedure of using alternate mempools is defined in [ERC-7562](./eip-7562.md ### Bundling -Bundling is the process where a node/bundler collects multiple UserOperations and create a single transaction to submit on-chain. +Bundling is the process where a node/bundler collects multiple UserOperations and creates a single transaction to submit on-chain. During bundling, the bundler should: @@ -475,42 +475,42 @@ When a bundler includes a bundle in a block it must ensure that earlier transact ### Error codes. While performing validation, the EntryPoint must revert on failures. During simulation, the calling bundler MUST be able to determine which entity (factory, account or paymaster) caused the failure. -The attribution of revert to entity is done using the call-tracing: the last entity called by the EntryPoint prior the revert is the entity that caused the revert. +The attribution of a revert to an entity is done using call-tracing: the last entity called by the EntryPoint prior to the revert is the entity that caused the revert. * For diagnostic purposes, the EntryPoint must only revert with explicit FailedOp() or FailedOpWithRevert() errors. * The message of the error starts with event code, AA## -* Event code starting with "AA1" signify an error during account creation -* Event code starting with "AA2" signify an error during account validation (validateUserOp) -* Event code starting with "AA3" signify an error during paymaster validation (validatePaymasterUserOp) +* Event code starting with "AA1" signifies an error during account creation +* Event code starting with "AA2" signifies an error during account validation (validateUserOp) +* Event code starting with "AA3" signifies an error during paymaster validation (validatePaymasterUserOp) ## Rationale -The main challenge with a purely smart contract wallet based account abstraction system is DoS safety: how can a block builder including an operation make sure that it will actually pay fees, without having to first execute the entire operation? +The main challenge with a purely smart contract wallet-based account abstraction system is DoS safety: how can a block builder including an operation make sure that it will actually pay fees, without having to first execute the entire operation? Requiring the block builder to execute the entire operation opens a DoS attack vector, as an attacker could easily send many operations that pretend to pay a fee but then revert at the last moment after a long execution. Similarly, to prevent attackers from cheaply clogging the mempool, nodes in the P2P network need to check if an operation will pay a fee before they are willing to forward it. -The first step is clean separation between validation (acceptance of UserOperation, and acceptance to pay) and execution. -In this proposal, we expect accounts to have a `validateUserOp` method that takes as input a `UserOperation`, and verify the signature and pay the fee. +The first step is a clean separation between validation (acceptance of UserOperation, and acceptance to pay) and execution. +In this proposal, we expect accounts to have a `validateUserOp` method that takes as input a `UserOperation`, verifies the signature and pays the fee. Only if this method returns successfully, the execution will happen. The entry point-based approach allows for a clean separation between verification and execution, and keeps accounts' logic simple. It enforces the simple rule that only after validation is successful (and the UserOp can pay), the execution is done, and also guarantees the fee payment. ### Validation Rules Rationale -The next step is protecting the bundlers from denial-of-service attacks by a mass number of UserOperation that appear to be valid (and pay) but that eventually revert, and thus block the bundler from processing valid UserOperations. +The next step is protecting the bundlers from denial-of-service attacks by a mass number of UserOperations that appear to be valid (and pay) but that eventually revert, and thus block the bundler from processing valid UserOperations. There are two types of UserOperations that can fail validation: -1. UserOperations that succeed in initial validation (and accepted into the mempool), but relay on environment state to fail later when attempting to include them in a block. +1. UserOperations that succeed in initial validation (and accepted into the mempool), but rely on the environment state to fail later when attempting to include them in a block. 2. UserOperations that are valid when checked independently, by fail when bundled together to be put on-chain. To prevent such rogue UserOperations, the bundler is required to follow a set of [restrictions on the validation function](./eip-7562.md), to prevent such denial-of-service attacks. ### Reputation Rationale. -UserOperation's storage access rules prevent them from interfere with each other. -But "global" entities - paymasters, factories and aggregators are accessed by multiple UserOperations, and thus might invalidate multiple previously-valid UserOperations. +UserOperation's storage access rules prevent them from interfering with each other. +But "global" entities - paymasters, factories and aggregators are accessed by multiple UserOperations, and thus might invalidate multiple previously valid UserOperations. -To prevent abuse, we throttle down (or completely ban for a period of time) an entity that causes invalidation of large number of UserOperations in the mempool. -To prevent such entities from "sybil-attack", we require them to stake with the system, and thus make such DoS attack very expensive. -Note that this stake is never slashed, and can be withdrawn any time (after unstake delay) +To prevent abuse, we throttle down (or completely ban for a period of time) an entity that causes invalidation of a large number of UserOperations in the mempool. +To prevent such entities from "Sybil-attack", we require them to stake with the system, and thus make such DoS attack very expensive. +Note that this stake is never slashed, and can be withdrawn at any time (after unstake delay) Unstaked entities are allowed, under the rules below. @@ -521,11 +521,11 @@ The stake value is not enforced on-chain, but specifically by each node while si ### Reputation scoring and throttling/banning for global entities [ERC-7562] defines a set of rules a bundler must follow when accepting UserOperations into the mempool. -It also descrbies the "reputation|" +It also descrbies the "reputation" ### Paymasters -Paymaster contracts allow abstraction of gas: having a contract, that is not the sender of the transaction, pay for the transaction fees. +Paymaster contracts allow the abstraction of gas: having a contract, that is not the sender of the transaction, to pay for the transaction fees. Paymaster architecture allows them to follow the model of "pre-charge, and later refund". E.g. a token-paymaster may pre-charge the user with the max possible price of the transaction, and refund the user with the excess afterwards. @@ -538,7 +538,7 @@ The wallet creation itself is done by a "factory" contract, with wallet-specific The factory is expected to use CREATE2 (not CREATE) to create the wallet, so that the order of creation of wallets doesn't interfere with the generated addresses. The `initCode` field (if non-zero length) is parsed as a 20-byte address, followed by "calldata" to pass to this address. This method call is expected to create a wallet and return its address. -If the factory does use CREATE2 or some other deterministic method to create the wallet, it's expected to return the wallet address even if the wallet has already been created. This is to make it easier for clients to query the address without knowing if the wallet has already been deployed, by simulating a call to `entryPoint.getSenderAddress()`, which calls the factory under the hood. +If the factory does use CREATE2 or some other deterministic method to create the wallet, it's expected to return the wallet address even if the wallet has already been created. This comes to make it easier for clients to query the address without knowing if the wallet has already been deployed, by simulating a call to `entryPoint.getSenderAddress()`, which calls the factory under the hood. When `initCode` is specified, if either the `sender` address points to an existing contract, or (after calling the initCode) the `sender` address still does not exist, then the operation is aborted. The `initCode` MUST NOT be called directly from the entryPoint, but from another address. @@ -547,7 +547,7 @@ For security reasons, it is important that the generated contract address will d This way, even if someone can create a wallet at that address, he can't set different credentials to control it. The factory has to be staked if it accesses global storage - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details. -NOTE: In order for the wallet to determine the "counterfactual" address of the wallet (prior its creation), +NOTE: In order for the wallet to determine the "counterfactual" address of the wallet (prior to its creation), it should make a static call to the `entryPoint.getSenderAddress()` ### Entry point upgrading @@ -580,7 +580,7 @@ The result `SHOULD` be set to the **userOpHash** if and only if the request pass * The `message` field SHOULD be set to the revert message from the paymaster * The `data` field MUST contain a `paymaster` value * **code: -32502** - transaction rejected because of opcode validation - * **code: -32503** - UserOperation out of time-range: either wallet or paymaster returned a time-range, and it is already expired (or will expire soon) + * **code: -32503** - UserOperation out of time-range: either wallet or paymaster returned a time-range, and it has already expired (or will expire soon) * The `data` field SHOULD contain the `validUntil` and `validAfter` values * The `data` field SHOULD contain a `paymaster` value, if this error was triggered by the paymaster * **code: -32504** - transaction rejected because paymaster (or signature aggregator) is throttled/banned @@ -591,6 +591,7 @@ The result `SHOULD` be set to the **userOpHash** if and only if the request pass * **code: -32506** - transaction rejected because wallet specified unsupported signature aggregator * The `data` field SHOULD contain an `aggregator` value * **code: -32507** - transaction rejected because of wallet signature check failed (or paymaster signature, if the paymaster uses its data as signature) + * **code: -32508** - transaction rejected because paymaster balance can't cover all pending UserOperations. ##### Example: @@ -669,7 +670,7 @@ Response: Estimate the gas values for a UserOperation. Given UserOperation optionally without gas limits and gas prices, return the needed gas limits. -The signature field is ignored by the wallet, so that the operation will not require user's approval. +The signature field is ignored by the wallet, so that the operation will not require the user's approval. Still, it might require putting a "semi-valid" signature (e.g. a signature in the right length) **Parameters**: @@ -733,9 +734,9 @@ Return a UserOperation receipt based on a hash (userOpHash) returned by `eth_sen * **sender** * **nonce** * **paymaster** the paymaster used for this userOp (or empty) -* **actualGasCost** - actual amount paid (by account or paymaster) for this UserOperation +* **actualGasCost** - the actual amount paid (by account or paymaster) for this UserOperation * **actualGasUsed** - total gas used by this UserOperation (including preVerification, creation, validation and execution) -* **success** boolean - did this execution completed without revert +* **success** boolean - did this execution completed without a revert * **reason** in case of revert, this is the revert reason * **logs** the logs generated by this UserOperation (not including logs of other UserOperations in the same bundle) * **receipt** the TransactionReceipt object. @@ -788,7 +789,7 @@ Returns [EIP-155](./eip-155.md) Chain ID. ### RPC methods (debug Namespace) -This api must only be available on testing mode and is required by the compatibility test suite. In production, any `debug_*` rpc calls should be blocked. +This api must only be available in testing mode and is required by the compatibility test suite. In production, any `debug_*` rpc calls should be blocked. #### * debug_bundler_clearState @@ -906,7 +907,7 @@ After setting mode to "manual", an explicit call to debug_bundler_sendBundleNow #### * debug_bundler_setReputation -Sets reputation of given addresses. parameters: +Sets the reputation of given addresses. parameters: **Parameters:** @@ -914,7 +915,7 @@ Sets reputation of given addresses. parameters: * `address` - The address to set the reputation for. * `opsSeen` - number of times a user operations with that entity was seen and added to the mempool - * `opsIncluded` - number of times a user operations that uses this entity was included on-chain + * `opsIncluded` - number of times user operations that use this entity was included on-chain * **EntryPoint** the entrypoint used by eth_sendUserOperation @@ -961,7 +962,7 @@ An array of reputation entries with the fields: * `address` - The address to set the reputation for. * `opsSeen` - number of times a user operations with that entity was seen and added to the mempool -* `opsIncluded` - number of times a user operations that uses this entity was included on-chain +* `opsIncluded` - number of times user operation that use this entity was included on-chain * `status` - (string) The status of the address in the bundler 'ok' | 'throttled' | 'banned'. ```json= From 82b1fda4f9d7c6051968d5691c00cb8ff98a3872 Mon Sep 17 00:00:00 2001 From: Duke tho Date: Fri, 16 Aug 2024 01:08:40 +0700 Subject: [PATCH 28/79] Add ERC: Ownership Delegation and Context for ERC-721 Merged by EIP-Bot. --- ERCS/erc-7695.md | 497 +++++++++++++++++++++++++++++++++++ assets/erc-7695/mortgage.svg | 3 + assets/erc-7695/rental.svg | 3 + 3 files changed, 503 insertions(+) create mode 100644 ERCS/erc-7695.md create mode 100644 assets/erc-7695/mortgage.svg create mode 100644 assets/erc-7695/rental.svg diff --git a/ERCS/erc-7695.md b/ERCS/erc-7695.md new file mode 100644 index 0000000000..5e1e652a97 --- /dev/null +++ b/ERCS/erc-7695.md @@ -0,0 +1,497 @@ +--- +eip: 7695 +title: Ownership Delegation and Context for ERC-721 +description: Introduces contexts and ownership delegation for ERC-721 tokens, expanding dApps and financial use cases without transferring ownership +author: Duc Tho Tran (@ducthotran2010) +discussions-to: https://ethereum-magicians.org/t/erc-7695-ownership-delegation-and-context-for-non-fungible-token/19716 +status: Draft +type: Standards Track +category: ERC +created: 2024-04-02 +requires: 165, 721 +--- + +## Abstract + +This standard is an extension for [ERC-721](./eip-721.md), designed to specify users for various contexts with a locking feature and allow temporary ownership delegation without changing the original owner. + +This EIP preserves the benefits and rights of the owner while expanding the utility of NFTs across various dApps by adding the concepts of Ownership Delegation and Contexts, which define specific roles: Controller and User, who can use the NFT within defined contexts. + +## Motivation + +For standard [ERC-721](./eip-721.md) NFTs, there are several use cases in financial applications, including: + +- Staking NFTs to earn rewards. +- Mortgaging an NFT to generate income. +- Granting users for different purposes like rental and token delegation—where someone pays to use tokens and pays another party to use the tokens. + +Traditionally, these applications require ownership transfers to lock the NFT in contracts. However, other decentralized applications (dApps) recognize token ownership as proof that the token owner is entitled to benefits within their reward systems, such as airdrops or tiered rewards. If token owners have their tokens locked in contracts, they are not eligible to receive benefits from holding these tokens, or the reward systems have to support as many contracts as possible to help these owners. + +This is because there is only an Owner role indicating the ownership rights, developing on top of [ERC-721](./eip-721.md) has often posed challenges. This proposal aims to solve these challenges by contextualizing the use case to be handled by controllers and distinguishing ownership rights from other roles at the standard level through an ownership delegation mechanism. Standardizing these measures, dApp developers can more easily construct infrastructure and protocols on top of this standard. + +## Specification + +The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. + +### Definitions + +This specification encompasses the following components: + +**Token Context** provides a specified use case of a token. It serves as the association relationship between Tokens and Contexts. Within each unique token context, there exists an allocated user who is authorized to utilize the token within that context. In a specified context, there are two distinct roles: + +- **Controller**: This role possesses the authority to control the context. +- **User**: This role signifies the primary token user within the given context. + +**Ownership Rights** of a token are defined to be able to: + +- Transfer that token to a new owner. +- Add token context(s): attaching that token to/from one or many contexts. +- Remove token context(s): detaching that token to/from one or many contexts. + +**Ownership Delegation** involves distinguishing between owner and ownership rights by delegating ownership to other accounts for a specific duration. During this period, owners temporarily cede ownership rights until the delegation expires. + +### Roles + +| Roles | Explanation / Permission | Quantity per Token | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| Owner | • Has **Ownership Rights** by default
• Delegates an account to hold **Ownership Rights** in a duration | $1$ | +| Ownership Delegatee | • Has **Ownership Rights** in a delegation duration
• Renounces before delegation expires | $1$ | +| Ownership Manager | • Is one who holds **Ownership Rights**
• If not delegated yet, it is referenced to **Owner**, otherwise it is referenced to **Ownership Delegatee** | $1$ | +| **Context Roles** | | $n$ | +| Controller | • Transfers controller
• Sets context user
• (Un)locks token transfer | $1$ per context | +| User | • Authorized to use token in its context | $1$ per context | + +### Interface + +**Smart contracts implementing this standard MUST implement all the functions in the `IERC7695` interface.** + +Smart contracts implementing this standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function and MUST return the constant value `true` if `0x486b6fba` is passed through the `interfaceID` argument. + +```solidity +/// Note: the ERC-165 identifier for this interface is 0x486b6fba. +interface IERC7695 /* is IERC721, IERC165 */ { + /// @dev This emits when a context is updated by any mechanism. + event ContextUpdated(bytes32 indexed ctxHash, address indexed controller, uint64 detachingDuration); + /// @dev This emits when a token is attached to a certain context by any mechanism. + event ContextAttached(bytes32 indexed ctxHash, uint256 indexed tokenId); + /// @dev This emits when a token is requested to detach from a certain context by any mechanism. + event ContextDetachmentRequested(bytes32 indexed ctxHash, uint256 indexed tokenId); + /// @dev This emits when a token is detached from a certain context by any mechanism. + event ContextDetached(bytes32 indexed ctxHash, uint256 indexed tokenId); + /// @dev This emits when a user is assigned to a certain context by any mechanism. + event ContextUserAssigned(bytes32 indexed ctxHash, uint256 indexed tokenId, address indexed user); + /// @dev This emits when a token is (un)locked in a certain context by any mechanism. + event ContextLockUpdated(bytes32 indexed ctxHash, uint256 indexed tokenId, bool locked); + /// @dev This emits when the ownership delegation is started by any mechanism. + event OwnershipDelegationStarted(uint256 indexed tokenId, address indexed delegatee, uint64 until); + /// @dev This emits when the ownership delegation is accepted by any mechanism. + event OwnershipDelegationAccepted(uint256 indexed tokenId, address indexed delegatee, uint64 until); + /// @dev This emits when the ownership delegation is stopped by any mechanism. + event OwnershipDelegationStopped(uint256 indexed tokenId, address indexed delegatee); + + /// @notice Gets the longest duration the detaching can happen. + function maxDetachingDuration() external view returns (uint64); + + /// @notice Gets controller address and detachment duration of a context. + /// @dev MUST revert if the context is not existent. + /// @param ctxHash A hash of context to query the controller. + /// @return controller The address of the context controller. + /// @return detachingDuration The duration must be waited for detachment in second(s). + function getContext(bytes32 ctxHash) external view returns (address controller, uint64 detachingDuration); + + /// @notice Creates a new context. + /// @dev MUST revert if the context is already existent. + /// MUST revert if the controller address is zero address. + /// MUST revert if the detaching duration is larger than max detaching duration. + /// MUST emit the event {ContextUpdated} to reflect context created and controller set. + /// @param controller The address that controls the created context. + /// @param detachingDuration The duration must be waited for detachment in second(s). + /// @param ctxMsg The message of new context to be used for hashing. + /// @return ctxHash Hash of the created context. + function createContext(address controller, uint64 detachingDuration, bytes calldata ctxMsg) + external + returns (bytes32 ctxHash); + + /// @notice Updates an existing context. + /// @dev MUST revert if method caller is not the current controller. + /// MUST revert if the context is non-existent. + /// MUST revert if the new controller address is zero address. + /// MUST revert if the detaching duration is larger than max detaching duration. + /// MUST emit the event {ContextUpdated} on success. + /// @param ctxHash Hash of the context to set. + /// @param newController The address of new controller. + /// @param newDetachingDuration The new duration must be waited for detachment in second(s). + function updateContext(bytes32 ctxHash, address newController, uint64 newDetachingDuration) external; + + /// @notice Queries if a token is attached to a certain context. + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to query. + /// @return True if the token is attached to the context, false if not. + function isAttachedWithContext(bytes32 ctxHash, uint256 tokenId) external view returns (bool); + + /// @notice Attaches a token with a certain context. + /// @dev See "attachContext rules" in "Token (Un)lock Rules". + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to be attached. + /// @param data Additional data with no specified format, MUST be sent unaltered in call to the {IERC7695ContextCallback} hook(s) on controller. + function attachContext(bytes32 ctxHash, uint256 tokenId, bytes calldata data) external; + + /// @notice Requests to detach a token from a certain context. + /// @dev See "requestDetachContext rules" in "Token (Un)lock Rules". + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to be detached. + /// @param data Additional data with no specified format, MUST be sent unaltered in call to the {IERC7695ContextCallback} hook(s) on controller. + function requestDetachContext(bytes32 ctxHash, uint256 tokenId, bytes calldata data) external; + + /// @notice Executes context detachment. + /// @dev See "execDetachContext rules" in "Token (Un)lock Rules". + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to be detached. + /// @param data Additional data with no specified format, MUST be sent unaltered in call to the {IERC7695ContextCallback} hook(s) on controller. + function execDetachContext(bytes32 ctxHash, uint256 tokenId, bytes calldata data) external; + + /// @notice Finds the context user of a token. + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to be detached. + /// @return user Address of the context user. + function getContextUser(bytes32 ctxHash, uint256 tokenId) external view returns (address user); + + /// @notice Updates the context user of a token. + /// @dev MUST revert if the method caller is not context controller. + /// MUST revert if the context is non-existent. + /// MUST revert if the token is not attached to the context. + /// MUST emit the event {ContextUserAssigned} on success. + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to be update. + /// @param user Address of the new user. + function setContextUser(bytes32 ctxHash, uint256 tokenId, address user) external; + + /// @notice Queries if the lock a token is locked in a certain context. + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to be queried. + /// @return True if the token context is locked, false if not. + function isTokenContextLocked(bytes32 ctxHash, uint256 tokenId) external view returns (bool); + + /// @notice (Un)locks a token in a certain context. + /// @dev See "setContextLock rules" in "Token (Un)lock Rules". + /// @param ctxHash Hash of a context. + /// @param tokenId The NFT to be queried. + /// @param lock New status to be (un)locked. + function setContextLock(bytes32 ctxHash, uint256 tokenId, bool lock) external; + + /// @notice Finds the ownership manager of a specified token. + /// @param tokenId The NFT to be queried. + /// @return manager Address of delegatee. + function getOwnershipManager(uint256 tokenId) external view returns(address manager); + + /// @notice Finds the ownership delegatee of a token. + /// @dev MUST revert if there is no (or an expired) ownership delegation. + /// @param tokenId The NFT to be queried. + /// @return delegatee Address of delegatee. + /// @return until The delegation expiry time. + function getOwnershipDelegatee(uint256 tokenId) external view returns (address delegatee, uint64 until); + + /// @notice Finds the pending ownership delegatee of a token. + /// @dev MUST revert if there is no (or an expired) pending ownership delegation. + /// @param tokenId The NFT to be queried. + /// @return delegatee Address of pending delegatee. + /// @return until The delegation expiry time in the future. + function pendingOwnershipDelegatee(uint256 tokenId) external view returns (address delegatee, uint64 until); + + /// @notice Starts ownership delegation and retains ownership until a specific timestamp. + /// @dev Replaces the pending delegation if any. + /// See "startDelegateOwnership rules" in "Ownership Delegation Rules". + /// @param tokenId The NFT to be delegated. + /// @param delegatee Address of new delegatee. + /// @param until The delegation expiry time. + function startDelegateOwnership(uint256 tokenId, address delegatee, uint64 until) external; + + /// @notice Accepts ownership delegation request. + /// @dev See "acceptOwnershipDelegation rules" in "Ownership Delegation Rules". + /// @param tokenId The NFT to be accepted. + function acceptOwnershipDelegation(uint256 tokenId) external; + + /// @notice Stops the current ownership delegation. + /// @dev See "stopOwnershipDelegation rules" in "Ownership Delegation Rules". + /// @param tokenId The NFT to be stopped. + function stopOwnershipDelegation(uint256 tokenId) external; +} +``` + +**Enumerable extension** + +The enumeration extension is OPTIONAL for this standard. This allows your contract to publish its full list of contexts and make them discoverable. When calling the `supportsInterface` function MUST return the constant value `true` if `0xcebf44b7` is passed through the `interfaceID` argument. + +```solidity +/// Note: the ERC-165 identifier for this interface is 0xcebf44b7. +interface IERC7695Enumerable /* is IERC165 */ { + /// @dev Returns a created context in this contract at `index`. + /// An index must be a value between 0 and {getContextCount}, non-inclusive. + /// Note: When using {getContext} and {getContextCount}, make sure you perform all queries on the same block. + function getContext(uint256 index) external view returns(bytes32 ctxHash); + + /// @dev Returns the number of contexts created in the contract. + function getContextCount() external view returns(uint256); + + /// @dev Returns a context attached to a token at `index`. + /// An index must be a value between 0 and {getAttachedContextCount}, non-inclusive. + /// Note: When using {getAttachedContext} and {getAttachedContextCount}, make sure you perform all queries on the same block. + function getAttachedContext(uint256 tokenId, uint256 index) external view returns(bytes32 ctxHash); + + /// @dev Returns the number of contexts attached to the token. + function getAttachedContextCount(uint256 tokenId) external view returns(uint256); +} +``` + +**Controller Interface** + +The controller is RECOMMENDED to be a contract and including callback methods to allow callbacks in cases where there are any attachment or detachment requests. When calling the `supportsInterface` function MUST return the constant value `true` if `0xad0491f1` is passed through the `interfaceID` argument. + +```solidity +/// Note: the ERC-165 identifier for this interface is 0xad0491f1. +interface IERC7695ContextCallback /* is IERC165 */ { + /// @dev This method is called once the token is attached by any mechanism. + /// This function MAY throw to revert and reject the attachment. + /// @param ctxHash The hash of context invoked this call. + /// @param tokenId NFT identifier which is being attached. + /// @param operator The address which called {attachContext} function. + /// @param data Additional data with no specified format. + function onAttached(bytes32 ctxHash, uint256 tokenId, address operator, bytes calldata data) external; + + /// @dev This method is called once the token detachment is requested by any mechanism. + /// @param ctxHash The hash of context invoked this call. + /// @param tokenId NFT identifier which is being requested for detachment. + /// @param operator The address which called {requestDetachContext} function. + /// @param data Additional data with no specified format. + function onDetachRequested(bytes32 ctxHash, uint256 tokenId, address operator, bytes calldata data) external; + + /// @dev This method is called once a token context is detached by any mechanism. + /// @param ctxHash The hash of context invoked this call. + /// @param tokenId NFT identifier which is being detached. + /// @param user The address of the context user which is being detached. + /// @param operator The address which called {execDetachContext} function. + /// @param data Additional data with no specified format. + function onExecDetachContext(bytes32 ctxHash, uint256 tokenId, address user, address operator, bytes calldata data) external; +} +``` + +### Ownership Delegation Rules + +**startDelegateOwnership rules** + +- MUST revert unless there is no delegation. +- MUST revert unless the method caller is the owner, an authorized operator of owner, or the approved address for this NFT. +- MUST revert unless the expiry time is in the future. +- MUST revert if the delegatee address is the owner or zero address. +- MUST revert if the token is not existent. +- MUST emit the event `OwnershipDelegationStarted` on success. +- After the above conditions are met, this function MUST replace the pending delegation if any. + +**acceptOwnershipDelegation rules** + +- MUST revert if there is no delegation. +- MUST revert unless the method caller is the delegatee, or an authorized operator of delegatee. +- MUST revert unless the expiry time is in the future. +- MUST emit the event `OwnershipDelegationAccepted` on success. +- After the above conditions are met, the delegatee MUST be recorded as the ownership manager until the delegation expires. + +**stopDelegateOwnership rules** + +- MUST revert unless the delegation is already accepted. +- MUST revert unless the expiry time is in the future. +- MUST revert unless the method caller is the delegatee, or an authorized operator of delegatee. +- MUST emit the event `OwnershipDelegationStopped` on success. +- After the above conditions are met, the owner MUST be recorded as the ownership manager. + +### **Token (Un)lock Rules** + +To be more explicit about how token (un)locked, these functions: + +- A token can be attached to a context using the `attachContext` method +- The `setContextLock` function MUST be called by the controller to (un)lock +- The `requestDetachContext` and `execDetachContext` functions MUST be called by the ownership manager and MUST operate with respect to the `IERC7695ContextCallback` hook functions + +A list of scenarios and rules follows. + +**Scenarios** + +**_Scenario#1:_** Context controller wants to (un)lock a token that is not requested for detachment. + +- `setContextLock` MUST be called successfully + +**_Scenario#2:_** Context controller wants to (un)lock a token that is requested for detachment. + +- `setContextLock` MUST be reverted + +**_Scenario#3:_** Ownership manager wants to (unlock and) detach a locked token and the callback controller implements `IERC7695ContextCallback`. + +- Caller MUST: + - Call `requestDetachContext` function successfully + - Wait at least context detaching duration (see variable `detachingDuration` in the `getContext` function) + - Call `execDetachContext` function successfully +- `requestDetachContext` MUST call the `onDetachRequested` function despite the call result +- `execDetachContext` MUST call the `onExecDetachContext` function despite the call result + +**_Scenario#4:_** Ownership manager wants to (unlock and) detach a locked token and the callback controller does not implement `IERC7695ContextCallback`. + +- Caller MUST: + - Call `requestDetachContext` function successfully + - Wait at least context detaching duration (see variable `detachingDuration` in the `getContext` function) + - Call `execDetachContext` function successfully + +**_Scenario#5:_** Ownership manager wants to detach an unlocked token and the callback controller implements `IERC7695ContextCallback`. + +- Caller MUST call `requestDetachContext` function successfully +- `requestDetachContext` MUST call the `onExecDetachContext` function despite the result +- `execDetachContext` MUST NOT be called + +**_Scenario#6:_** Ownership manager wants to detach an unlocked token and the callback controller does not implement `IERC7695ContextCallback`. + +- Caller MUST call `requestDetachContext` function successfully +- `execDetachContext` MUST NOT be called + +**Rules** + +**attachContext rules** + +- MUST revert unless the method caller is the ownership manager, an authorized operator of ownership manager, or the approved address for this NFT (if the token is not being delegated). +- MUST revert if the context is non-existent. +- MUST revert if the token is already attached to the context. +- MUST emit the event `ContextAttached`. +- After the above conditions are met, this function MUST check if the controller address is a smart contract (e.g. code size > 0). If so, it MUST call `onAttached` and MUST revert if the call is failed. + - The `data` argument provided by the caller MUST be passed with its contents unaltered to the `onAttached` hook function via its `data` argument. + +**setContextLock rules** + +- MUST revert if the context is non-existent. +- MUST revert if the token is not attached to the context. +- MUST revert if a detachment request has previously been made. +- MUST revert if the method caller is not context controller. +- MUST emit the event `ContextLockUpdated` on success. + +**requestDetachContext rules** + +- MUST revert if a detachment request has previously been made. +- MUST revert unless the method caller is the context controller, the ownership manager, an authorized operator of the ownership manager, or the approved address for this NFT (if the token is not being delegated). +- If the caller is context controller or the token context is not locked, MUST emit the `ContextDetached` event. After the above conditions are met, this function MUST check if the controller address is a smart contract (e.g. code size > 0). If so, it MUST call `onExecDetachContext` and the call result MUST be skipped. + - The `data` argument provided by the caller MUST be passed with its contents unaltered to the `onExecDetachContext` hook function via its `data` argument. +- If the token context is locked, MUST emit the `ContextDetachRequested` event. After the above conditions are met, this function MUST check if the controller address is a smart contract (e.g. code size > 0). If so, it MUST call `onDetachRequested` and the call result MUST be skipped. + - The `data` argument provided by the caller MUST be passed with its contents unaltered to the `onDetachRequested` hook function via its `data` argument. + +**execDetachContext rules** + +- MUST revert unless the method caller is the ownership manager, an authorized operator of ownership manager, or the approved address for this NFT (if the token is not being delegated). +- MUST revert unless a detachment request has previously been made and the specified detaching duration has passed (use variable `detachingDuration` in the `getContext` function when requesting detachment). +- MUST emit the `ContextDetached` event. +- After the above conditions are met, this function MUST check if the controller address is a smart contract (e.g. code size > 0). If so, it MUST call `onExecDetachContext` and the call result MUST be skipped. + - The `data` argument provided by the caller MUST be passed with its contents unaltered to the `onExecDetachContext` hook function via its `data` argument. + +### Additional Transfer Rules + +In addition to extending from [ERC-721](./eip-721.md) for the transfer mechanism when transferring an NFT, the implementation: + +- MUST revert unless the method caller is the ownership manager, an authorized operator of ownership manager, or the approved address for this NFT (if the token is not being delegated). +- MUST revoke ownership delegation if any. +- MUST detach every attached context: + - MUST revert unless a detachment request has previously been made and the specified detaching duration has passed (use variable `detachingDuration` in the `getContext` function when requesting detachment) if the token is locked. + - MUST check if the controller address is a smart contract (e.g. code size > 0). If so, it MUST call the `onExecDetachContext` function (with an empty `data` argument `""`) and the call result MUST be skipped. + +## Rationale + +When designing the proposal, we considered the following concerns. + +### Multiple contexts for multiple use cases + +This proposal is centered around Token Context to allow for the creation of distinct contexts tailored to various decentralized applications (dApps). The context controller assumes the role of facilitating (rental or delegation) dApps, by enabling the granting of usage rights to another user without modifying the NFT's owner record. Besides, this proposal provides the lock feature for contexts to ensure trustlessness in performing these dApps, especially staking cases. + +### Providing an unlock mechanism for owners + +By providing an unlock mechanism for owners, this approach allows owners to unlock their tokens independently, without relying on the context controller to initiate the process. This prevents scenarios where, should the controller lose control, owners would be unable to unlock their tokens. + +### Attachment and detachment callbacks + +The callback results of the `onDetachRequested` and `onExecDetachContext` functions in the **Token (Un)lock Rules** are skipped because we are intentionally removing the controller's ability to stop detachment, ensuring token detachment is independent of the controller's actions. + +Additionally, to retain the permission to reject incoming attachments, the operation reverts if the call to the `onAttach` function fails. + +### Ownership delegation + +This feature provides a new approach by separating the owner and ownership. Primarily designed to facilitate delegating for third parties, it enables delegating another account as the manager of ownership, distinct from the owner. + +Unlike `approve` or `setApprovalForAll` methods, which grant permission to other accounts while maintaining ownership status. Ownership delegation goes beyond simply granting permissions; it involves transferring the owner's rights to the delegatee, with provisions for automatic reversion upon expiration. This mechanism prevents potential abuses, such as requesting mortgages and transfers to alternative accounts if the owner retains ownership rights. + +The **2-step delegation** process is provided to prevent mistakes in assigning delegatees, it must be done through two steps: offer and confirm. In cases the delegation needs to be canceled before its scheduled expiry, the delegatees can invoke `stopOwnershipDelegation` method. + +### Transfer method mechanism + +As part of the integration with the transfer method, we extended its implicit behavior to include token approval: + +- **Reset Ownership Delegation:** Automatically resets ownership delegations. The `OwnershipDelegationStopped` event is intentionally not emitted. +- **Detach All Contexts:** Similarly, all contexts associated with the token are detached if none of them is locked. The `ContextDetached` event is intentionally not emitted. + +These modifications are to ensure trustlessness and gas efficiency during token transfers, providing a seamless experience for users. + +## Backwards Compatibility + +This proposal is backward compatible with [ERC-721](./eip-721.md). + +## Security Considerations + +### Detaching duration + +When developing this token standard to serve multiple contexts: + +- The contract deployer should establish an appropriate upper threshold for detachment delay (by `maxDetachingDuration` method). +- The context owner should anticipate potential use cases and establish an appropriate period not larger than the upper threshold. + +This precaution is essential to mitigate the risk of the owner abusing systems by spamming listings and transferring tokens to another owner in a short time. + +### Duplicated token usage + +When initiating a new context, the context controllers should track all other contexts within the NFT contract to prevent duplicated usage. + +For example, suppose a scenario where a token is locked for rental purposes within a particular game. If that game introduces another context (e.g. supporting delegation in that game), it could lead to duplicated token usage within the game, despite being intended for different contexts. + +In such cases, a shared context for rental and delegation purposes can be considered. Or there must be some restrictions on the new delegation context to prevent reusing that token in the game. + +### Ownership Delegation Buffer Time + +When constructing systems that rely on ownership delegation for product development, it is imperative to incorporate a buffer time (of at least `maxDetachingDuration` seconds) when requesting ownership delegation. This precaution is essential to mitigate the risk of potential abuse, particularly if one of the associated contexts locks the token until the delegation time expires. +For example, consider a scenario where a mortgage contract is built atop this standard, which has a maximum detaching duration of 7 days, while the required delegation period is only 3 days. In such cases, without an adequate buffer time, the owner could exploit the system by withdrawing funds and invoking the relevant context to lock the token, thus preventing its unlock and transfer. + +### Validating Callback Callers + +To enhance security and integrity in interactions between contracts, it is essential to validate the caller of any callback function while implementing the `IERC7695ContextCallback`. This validation ensures that the `msg.sender` of the callback is indeed the expected contract address, typically the token contract or a designated controller contract. Such checks are crucial for preventing unauthorized actions that could be executed by malicious entities pretending to be a legitimate contract. + +### Recommended practices + +**Rental** + +This is a typical use case for rentals, supposing A(owner) owns a token and wants to list his/her token for rent, and B(user) wants to rent the token to play in a certain game. + +![Rental Flow](../assets/eip-7695/rental.svg) + +**Mortgage** + +When constructing collateral systems, it is recommended to support token owners who wish to rent out their tokens while using them for collateral lending. This approach enhances the appeal of mortgage systems, creating a more attractive and versatile financial ecosystem that meets many different needs. + +This is a typical use case for mortgages, supposing A(owner) owns a token and wants to mortgage, and B(lender) wants to earn interest by lending their funds to A. + +![Mortgage Flow](../assets/eip-7695/mortgage.svg) + +### Risk of Token Owner + +**Phishing attacks** + +It is crucial to note that the owner role has the ability to delegate ownership to another account, allowing it to authorize transfers out of the respective wallet. Consequently, some malicious actors could deceive the token owner into delegating them as a delegatee by invoking the `startDelegateOwnership` method. This risk can be considered the same as the `approve` or `setApprovalForAll` methods. + +**Ownership rights loss** + +When interacting with a contract system (e.g. mortgage), where owners have to delegate their ownership rights to the smart contract, it's imperative to: + +- Ensure the timeframe for delegation is reasonable and not excessively distant. If the contract mandates a delegation period that extends too far into the future, make sure it includes a provision to revoke ownership delegation when specific conditions are met. Failing to include such a provision could lead to the loss of ownership rights until the delegation expires. +- Be aware that if the contract owner or their operator is compromised, the token ownership can be altered. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/assets/erc-7695/mortgage.svg b/assets/erc-7695/mortgage.svg new file mode 100644 index 0000000000..609d66f790 --- /dev/null +++ b/assets/erc-7695/mortgage.svg @@ -0,0 +1,3 @@ + + +NFTMortgageNFTMortgagealt[NFT is locked]alt[A kept agreement][A breached agreement]B(Lender)A(Owner)start delegate ownership for [Mortgage]1use NFT to request a loan2fill a loan3accept ownership delegation4pay debt & finish agreement5stop ownership delegation6refund7revoke agreement8request unlock (and detach)9wait delay time10claim NFT11invoke transfer12transfer NFT to B13B(Lender)A(Owner) \ No newline at end of file diff --git a/assets/erc-7695/rental.svg b/assets/erc-7695/rental.svg new file mode 100644 index 0000000000..92ef30dead --- /dev/null +++ b/assets/erc-7695/rental.svg @@ -0,0 +1,3 @@ + + +NFTRentalNFTRentalRental is the context controllerloop[each period]alt[A & B kept agreement][B breached agreement][A breached agreement]B(User)A(Owner)list NFT for rent1fill funds and rent2lock NFT3set B as [User]4request claim funds5transfer funds in the period6finish agreement7revoke agreement8revoke agreement9unlock NFT10set A as [User]11transfer min funds12refund13B(User)A(Owner) \ No newline at end of file From e3f5bbea37291eb6fc65dbc8bbf9c7fe794c4852 Mon Sep 17 00:00:00 2001 From: T1MOH593 <79079180+T1MOH593@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:45:21 +0400 Subject: [PATCH 29/79] Fix incorrect comment copied from previous function (#429) --- assets/erc-3448/MetaProxyFactory.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/erc-3448/MetaProxyFactory.sol b/assets/erc-3448/MetaProxyFactory.sol index e7c3679124..e8286b36ef 100644 --- a/assets/erc-3448/MetaProxyFactory.sol +++ b/assets/erc-3448/MetaProxyFactory.sol @@ -85,7 +85,7 @@ contract MetaProxyFactory { mstore(ptr, length) ptr := add(ptr, 32) - // The size is deploy code + contract code + calldatasize - 4 + 32. + // The size is deploy code + contract code + length + 32. addr := create(0, start, sub(ptr, start)) } } From 49d81df6ba372101296790426f37a2d1d668c47e Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 20 Aug 2024 10:18:35 -0400 Subject: [PATCH 30/79] Update erc-7588.md (#597) --- ERCS/erc-7588.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7588.md b/ERCS/erc-7588.md index 2cd4682820..62ce8f5d9b 100644 --- a/ERCS/erc-7588.md +++ b/ERCS/erc-7588.md @@ -4,7 +4,8 @@ title: Blob Transactions Metadata JSON Schema description: Attaching metadata to blobs carried by blob transactions author: Gavin Fu (@gavfu), Leo Wang (@wanglie1986), Bova Chen (@appoipp), Aiden X (@4ever9) discussions-to: https://ethereum-magicians.org/t/erc7588-attaching-metadata-to-blobs-carried-by-blob-transactions/17873 -status: Review +status: Last Call +last-call-deadline: 2024-09-03 type: Standards Track category: ERC created: 2024-01-01 @@ -149,4 +150,4 @@ This EIP does not introduce any new security risks or vulnerabilities, as the me ## Copyright -Copyright and related rights waived via [CC0](../LICENSE.md). \ No newline at end of file +Copyright and related rights waived via [CC0](../LICENSE.md). From 6e37a79f874148f01cc39ca716be774ae463af50 Mon Sep 17 00:00:00 2001 From: "drCathieSo.eth" Date: Tue, 20 Aug 2024 16:20:52 +0200 Subject: [PATCH 31/79] Website: Move ERC-7007 to Last Call Merged by EIP-Bot. --- ERCS/erc-7007.md | 133 +- .../erc-7007/contracts/ERC7007Enumerable.sol | 7 +- assets/erc-7007/contracts/ERC7007Opml.sol | 45 +- assets/erc-7007/contracts/ERC7007Zkml.sol | 23 +- assets/erc-7007/contracts/IERC7007.sol | 20 +- .../erc-7007/contracts/IERC7007Updatable.sol | 6 +- assets/erc-7007/package-lock.json | 16534 ---------------- assets/erc-7007/test/test.js | 8 +- 8 files changed, 115 insertions(+), 16661 deletions(-) delete mode 100644 assets/erc-7007/package-lock.json diff --git a/ERCS/erc-7007.md b/ERCS/erc-7007.md index 34801db404..caac5be17b 100644 --- a/ERCS/erc-7007.md +++ b/ERCS/erc-7007.md @@ -4,7 +4,8 @@ title: Verifiable AI-Generated Content Token description: An ERC-721 extension for verifiable AI-generated content tokens using Zero-Knowledge and Optimistic Machine Learning techniques author: Cathie So (@socathie), Xiaohang Yu (@xhyumiracle), Conway (@0x1cc), Lee Ting Ting (@tina1998612), Kartin discussions-to: https://ethereum-magicians.org/t/eip-7007-zkml-aigc-nfts-an-erc-721-extension-interface-for-zkml-based-aigc-nfts/14216 -status: Review +status: Last Call +last-call-deadline: 2024-09-30 type: Standards Track category: ERC created: 2023-05-10 @@ -13,17 +14,17 @@ requires: 165, 721 ## Abstract -The verifiable AI-generated content (AIGC) non-fungible token (NFT) standard is an extension of the [ERC-721](./eip-721.md) token standard for AIGC. It proposes a set of interfaces for basic interactions and enumerable interactions for AIGC-NFTs. The standard includes a `mint` and `verify` function interface, a new `Mint` event, optional `Enumerable` and `Updatable` extensions, and a JSON schema for AIGC-NFT metadata. Additionally, it incorporates Zero-Knowledge Machine Learning (zkML) and Optimistic Machine Learning (opML) capabilities to enable verification of AIGC data correctness. In this standard, the `tokenId` is indexed by the `prompt`. +The verifiable AI-generated content (AIGC) non-fungible token (NFT) standard is an extension of the [ERC-721](./eip-721.md) token standard for AIGC. It proposes a set of interfaces for basic interactions and enumerable interactions for AIGC-NFTs. The standard includes an `addAigcData` and `verify` function interface, a new `AigcData` event, optional `Enumerable` and `Updatable` extensions, and a JSON schema for AIGC-NFT metadata. Additionally, it incorporates Zero-Knowledge Machine Learning (zkML) and Optimistic Machine Learning (opML) capabilities to enable verification of AIGC data correctness. In this standard, the `tokenId` is indexed by the `prompt`. ## Motivation -The verifiable AIGC-NFT standard aims to extend the existing [ERC-721](./eip-721.md) token standard to accommodate the unique requirements of AI-generated content NFTs representing models in a collection. This standard provides interfaces to use zkML or opML to verify whether or not the AIGC data for an NFT is generated from a certain ML model with a certain input (prompt). The proposed interfaces allow for additional functionality related to minting, verifying, and enumerating AIGC-NFTs. Additionally, the metadata schema provides a structured format for storing information related to AIGC-NFTs, such as the prompt used to generate the content and the proof of ownership. +The verifiable AIGC-NFT standard aims to extend the existing [ERC-721](./eip-721.md) token standard to accommodate the unique requirements of AI-generated content NFTs representing models in a collection. This standard provides interfaces to use zkML or opML to verify whether or not the AIGC data for an NFT is generated from a certain ML model with a certain input (prompt). The proposed interfaces allow for additional functionality related to adding AIGC data, verifying, and enumerating AIGC-NFTs. Additionally, the metadata schema provides a structured format for storing information related to AIGC-NFTs, such as the prompt used to generate the content and the proof of ownership. This standard supports two primary types of proofs: validity proofs and fraud proofs. In practice, zkML and opML are commonly employed as the prevailing instances for these types of proofs. Developers can choose their preferred ones. In the zkML scenario, this standard enables model owners to publish their trained model and its ZKP verifier to Ethereum. Any user can claim an input (prompt) and publish the inference task. Any node that maintains the model and the proving circuit can perform the inference and proving, and submit the output of inference and the ZK proof for the inference trace to the verifier. The user that initiates the inference task will own the output for the inference of that model and input (prompt). -In the opML scenario, this standard enables model owners to publish their trained model to Ethereum. Any user can claim an input (prompt) and publish the inference task. Any node that maintains the model can perform the inference and submit the inference output. Other nodes can challenge this result within a predefined challenge period. At the end of the challenge period, the user can verify that they own the output for the inference of that model and prompt. +In the opML scenario, this standard enables model owners to publish their trained model to Ethereum. Any user can claim an input (prompt) and publish the inference task. Any node that maintains the model can perform the inference and submit the inference output. Other nodes can challenge this result within a predefined challenge period. At the end of the challenge period, the user can verify that they own the output for the inference of that model and prompt, and update the AIGC data as needed. This capability is especially beneficial for AI model authors and AI content creators seeking to capitalize on their creations. With this standard, every input prompt and its resulting content can be securely verified on the blockchain. This opens up opportunities for implementing revenue-sharing mechanisms for all AI-generated content (AIGC) NFT sales. AI model authors can now share their models without concerns that open-sourcing will diminish their financial value. @@ -32,10 +33,11 @@ An example workflow of a zkML AIGC NFT project compliant with this proposal is a ![zkML Suggested Workflow](../assets/eip-7007/workflow.png) There are 4 components in this workflow: -* ML model - contains weights of a pre-trained model; given an inference input, generates the output -* zkML prover - given an inference task with input and output, generates a ZK proof -* AIGC-NFT smart contract - contract compliant with this proposal, with full [ERC-721](./eip-721.md) functionalities -* Verifier smart contract - implements a `verify` function, given an inference task and its ZK proof, returns the verification result as a boolean + +- ML model - contains weights of a pre-trained model; given an inference input, generates the output +- zkML prover - given an inference task with input and output, generates a ZK proof +- AIGC-NFT smart contract - contract compliant with this proposal, with full [ERC-721](./eip-721.md) functionalities +- Verifier smart contract - implements a `verify` function, given an inference task and its ZK proof, returns the verification result as a boolean ## Specification @@ -43,47 +45,37 @@ The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SH **Every compliant contract must implement the `IERC7007`, [`ERC721`](./eip-721.md), and [`ERC165`](./eip-165.md) interfaces.** -The verifiable AIGC-NFT standard includes the following interfaces: +The verifiable AIGC-NFT standard includes the following interfaces: -`IERC7007`: Defines a `mint` function and a `Mint` event for minting AIGC-NFTs. Defines a `verify` function to check the validity of the combination of prompt and aigcData using zkML/opML techniques. +`IERC7007`: Defines an `addAigcData` function and an `AigcData` event for adding AIGC data to AIGC-NFTs. Defines a `verify` function to check the validity of the combination of prompt and aigcData using zkML/opML techniques. ```solidity pragma solidity ^0.8.18; /** * @dev Required interface of an ERC7007 compliant contract. - * Note: the ERC-165 identifier for this interface is 0x7e52e423. + * Note: the ERC-165 identifier for this interface is 0x702c55a6. */ interface IERC7007 is IERC165, IERC721 { /** - * @dev Emitted when `tokenId` token is minted. + * @dev Emitted when `tokenId` token's AIGC data is added. */ - event Mint( - address indexed to, + event AigcData( uint256 indexed tokenId, bytes indexed prompt, - bytes aigcData, - string uri, + bytes indexed aigcData, bytes proof ); /** - * @dev Mint token at `tokenId` given `to`, `prompt`, `aigcData`, `uri`, and `proof`. `proof` means that we input the ZK proof when using zkML and byte zero when using opML as the verification method. - * - * Requirements: - * - `tokenId` must not exist.' - * - verify(`prompt`, `aigcData`, `proof`) must return true. - * - * Optional: - * - `proof` should not include `aigcData` to save gas. + * @dev Add AIGC data to token at `tokenId` given `prompt`, `aigcData`, and `proof`. */ - function mint( - address to, + function addAigcData( + uint256 tokenId, bytes calldata prompt, bytes calldata aigcData, - string calldata uri, bytes calldata proof - ) external returns (uint256 tokenId); + ) external; /** * @dev Verify the `prompt`, `aigcData`, and `proof`. @@ -129,6 +121,7 @@ pragma solidity ^0.8.18; /** * @title ERC7007 Token Standard, optional updatable extension + * Note: the ERC-165 identifier for this interface is 0x3f37dce2. */ interface IERC7007Updatable is IERC7007 { /** @@ -136,8 +129,7 @@ interface IERC7007Updatable is IERC7007 { */ function update( bytes calldata prompt, - bytes calldata aigcData, - string calldata uri + bytes calldata aigcData ) external; /** @@ -146,8 +138,7 @@ interface IERC7007Updatable is IERC7007 { event Update( uint256 indexed tokenId, bytes indexed prompt, - bytes indexed aigcData, - string uri + bytes indexed aigcData ); } ``` @@ -156,44 +147,44 @@ interface IERC7007Updatable is IERC7007 { ```json { - "title": "AIGC Metadata", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Identifies the asset to which this NFT represents" - }, - "description": { - "type": "string", - "description": "Describes the asset to which this NFT represents" - }, - "image": { - "type": "string", - "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive." - }, - "prompt": { - "type": "string", - "description": "Identifies the prompt from which this AIGC NFT generated" - }, - "aigc_type": { - "type": "string", - "description": "image/video/audio..." - }, - "aigc_data": { - "type": "string", - "description": "A URI pointing to a resource with mime type image/* representing the asset to which this AIGC NFT represents." - }, - "proof_type": { - "type": "string", - "description": "validity (zkML) or fraud (opML)" - } + "title": "AIGC Metadata", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Identifies the asset to which this NFT represents" + }, + "description": { + "type": "string", + "description": "Describes the asset to which this NFT represents" + }, + "image": { + "type": "string", + "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive." + }, + "prompt": { + "type": "string", + "description": "Identifies the prompt from which this AIGC NFT generated" + }, + "aigc_type": { + "type": "string", + "description": "image/video/audio..." + }, + "aigc_data": { + "type": "string", + "description": "A URI pointing to a resource with mime type image/* representing the asset to which this AIGC NFT represents." + }, + "proof_type": { + "type": "string", + "description": "validity (zkML) or fraud (opML)" } + } } ``` ### ML Model Publication -While this standard does not describe the Machine Learning model publication stage, it is natural and recommended to publish the commitment of the Model to Ethereum separately, before any actual `mint` actions. The model commitment schema choice lies on the AIGC-NFT project issuer party. The commitment should be checked inside the implementation of the `verify` function. +While this standard does not describe the Machine Learning model publication stage, it is natural and recommended to publish the commitment of the Model to Ethereum separately, before any actual `addAigcData` actions. The model commitment schema choice lies on the AIGC-NFT project issuer party. The commitment should be checked inside the implementation of the `verify` function. ## Rationale @@ -203,15 +194,15 @@ This specification sets the `tokenId` to be the hash of its corresponding `promp ### Generalization to Different Proof Types -This specification accommodates two proof types: validity proofs for zkML and fraud proofs for opML. Function arguments in `mint` and `verify` are designed for generality, allowing for compatibility with both proof systems. Moreover, the specification includes an updatable extension that specifically serves the requirements of opML. +This specification accommodates two proof types: validity proofs for zkML and fraud proofs for opML. Function arguments in `addAigcData` and `verify` are designed for generality, allowing for compatibility with both proof systems. Moreover, the specification includes an updatable extension that specifically serves the requirements of opML. ### `verify` interface -We specify a `verify` interface to enforce the correctness of `aigcData`. It is defined as a view function to reduce gas cost. `verify` should return true if and only if `aigcData` is finalized in both zkML and opML. In zkML, it must verify the ZK proof, i.e. `proof`; in opML, it must make sure that the challenging period is finalized, and that the `aigcData` is up-to-date, i.e. has been updated after finalization. Additionally, `proof` can be *empty* in opML. +We specify a `verify` interface to enforce the correctness of `aigcData`. It is defined as a view function to reduce gas cost. `verify` should return true if and only if `aigcData` is finalized in both zkML and opML. In zkML, it must verify the ZK proof, i.e. `proof`; in opML, it must make sure that the challenging period is finalized, and that the `aigcData` is up-to-date, i.e. has been updated after finalization. Additionally, `proof` can be _empty_ in opML. -### `mint` interface +### `addAigcData` interface -We specify a `mint` interface to bind the prompt and `aigcData` with `tokenId`. Notably, it acts differently in zkML and opML cases. In zkML, `mint` should make sure `verify` returns `true`. While in opML, it can be called before finalization. The consideration here is that, limited by the proving difficulty, zkML usually targets simple model inference tasks in practice, making it possible to provide a proof within an acceptable time frame. On the other hand, opML enables large model inference tasks, with a cost of longer confirmation time to achieve the approximate same security level. Mint until opML finalization may not be the best practice considering the existing optimistic protocols. +We specify an `addAigcData` interface to bind the prompt and `aigcData` with `tokenId`. This function provides flexibility for different minting implementations. Notably, it acts differently in zkML and opML cases. In zkML, `addAigcData` should make sure `verify` returns `true`. While in opML, it can be called before finalization. The consideration here is that, limited by the proving difficulty, zkML usually targets simple model inference tasks in practice, making it possible to provide a proof within an acceptable time frame. On the other hand, opML enables large model inference tasks, with a cost of longer confirmation time to achieve the approximate same security level. Mint until opML finalization may not be the best practice considering the existing optimistic protocols. ### Naming Choice on `update` @@ -227,8 +218,8 @@ The reference implementation includes sample implementations of the [ERC-7007](. ## Reference Implementation -* ERC-7007 for [zkML](../assets/eip-7007/contracts/ERC7007Zkml.sol) and [opML](../assets/eip-7007/contracts/ERC7007Opml.sol) -* [ERC-7007 Enumerable Extension](../assets/eip-7007/contracts/ERC7007Enumerable.sol) +- ERC-7007 for [zkML](../assets/eip-7007/contracts/ERC7007Zkml.sol) and [opML](../assets/eip-7007/contracts/ERC7007Opml.sol) +- [ERC-7007 Enumerable Extension](../assets/eip-7007/contracts/ERC7007Enumerable.sol) ## Security Considerations @@ -242,4 +233,4 @@ In the opML scenario, it is important to consider that the `aigcData` might chan ## Copyright -Copyright and related rights waived via [CC0](../LICENSE.md). +Copyright and related rights waived via [CC0](../LICENSE.md). \ No newline at end of file diff --git a/assets/erc-7007/contracts/ERC7007Enumerable.sol b/assets/erc-7007/contracts/ERC7007Enumerable.sol index fe096209df..0271ab23a8 100644 --- a/assets/erc-7007/contracts/ERC7007Enumerable.sol +++ b/assets/erc-7007/contracts/ERC7007Enumerable.sol @@ -29,17 +29,14 @@ abstract contract ERC7007Enumerable is ERC7007Zkml, IERC7007Enumerable { interfaceId == type(IERC7007Enumerable).interfaceId || super.supportsInterface(interfaceId); } - - /** - * @dev See {IERC7007-mint}. - */ + function mint( address to, bytes calldata prompt_, bytes calldata aigcData, string calldata uri, bytes calldata proof - ) public virtual override(ERC7007Zkml, IERC7007) returns (uint256 tokenId_) { + ) public virtual override returns (uint256 tokenId_) { tokenId_ = ERC7007Zkml.mint(to, prompt_, aigcData, uri, proof); prompt[tokenId_] = string(prompt_); tokenId[prompt_] = tokenId_; diff --git a/assets/erc-7007/contracts/ERC7007Opml.sol b/assets/erc-7007/contracts/ERC7007Opml.sol index 40b8f12ebe..b6164d27a0 100644 --- a/assets/erc-7007/contracts/ERC7007Opml.sol +++ b/assets/erc-7007/contracts/ERC7007Opml.sol @@ -23,17 +23,14 @@ contract ERC7007Opml is ERC165, IERC7007Updatable, ERC721URIStorage { ) ERC721(name_, symbol_) { opmlLib = opmlLib_; } - - /** - * @dev See {IERC7007-mint}. - */ + function mint( address to, bytes calldata prompt, bytes calldata aigcData, string calldata uri, bytes calldata proof - ) public virtual override returns (uint256 tokenId) { + ) public returns (uint256 tokenId) { tokenId = uint256(keccak256(prompt)); _safeMint(to, tokenId); string memory tokenUri = string( @@ -48,11 +45,23 @@ contract ERC7007Opml is ERC165, IERC7007Updatable, ERC721URIStorage { ) ); _setTokenURI(tokenId, tokenUri); - + addAigcData(tokenId, prompt, aigcData, proof); + } + + /** + * @dev See {IERC7007-addAigcData}. + */ + function addAigcData( + uint256 tokenId, + bytes calldata prompt, + bytes calldata aigcData, + bytes calldata proof + ) public virtual override { + require(ownerOf(tokenId) != address(0), "ERC7007: nonexistent token"); + require(tokenIdToRequestId[tokenId] == 0, "ERC7007: requestId already exists"); tokenIdToRequestId[tokenId] = IOpmlLib(opmlLib).initOpmlRequest(prompt); IOpmlLib(opmlLib).uploadResult(tokenIdToRequestId[tokenId], aigcData); - - emit Mint(to, tokenId, prompt, aigcData, uri, proof); + emit AigcData(tokenId, prompt, aigcData, proof); } /** @@ -74,25 +83,13 @@ contract ERC7007Opml is ERC165, IERC7007Updatable, ERC721URIStorage { */ function update( bytes calldata prompt, - bytes calldata aigcData, - string calldata uri + bytes calldata aigcData ) public virtual override { require(verify(prompt, aigcData, prompt), "ERC7007: invalid aigcData"); // proof argument is not used in verify() function for opML, so we can pass prompt as proof uint256 tokenId = uint256(keccak256(prompt)); - string memory tokenUri = string( - abi.encodePacked( - "{", - uri, - ', "prompt": "', - string(prompt), - '", "aigc_data": "', - string(aigcData), - '"}' - ) - ); - require(keccak256(bytes(tokenUri)) != keccak256(bytes(tokenURI(tokenId))), "ERC7007: token uri is not changed"); - - emit Update(tokenId, prompt, aigcData, uri); + require(ownerOf(tokenId) != address(0), "ERC7007: nonexistent token"); + // TODO: should update tokenURI with new aigcData + emit Update(tokenId, prompt, aigcData); } /** diff --git a/assets/erc-7007/contracts/ERC7007Zkml.sol b/assets/erc-7007/contracts/ERC7007Zkml.sol index 2478115133..b8abf9978f 100644 --- a/assets/erc-7007/contracts/ERC7007Zkml.sol +++ b/assets/erc-7007/contracts/ERC7007Zkml.sol @@ -23,19 +23,17 @@ contract ERC7007Zkml is ERC165, IERC7007, ERC721URIStorage { verifier = verifier_; } - /** - * @dev See {IERC7007-mint}. - */ function mint( address to, bytes calldata prompt, bytes calldata aigcData, string calldata uri, bytes calldata proof - ) public virtual override returns (uint256 tokenId) { - require(verify(prompt, aigcData, proof), "ERC7007: invalid proof"); + ) public virtual returns (uint256 tokenId) { tokenId = uint256(keccak256(prompt)); _safeMint(to, tokenId); + addAigcData(tokenId, prompt, aigcData, proof); + string memory tokenUri = string( abi.encodePacked( "{", @@ -48,7 +46,20 @@ contract ERC7007Zkml is ERC165, IERC7007, ERC721URIStorage { ) ); _setTokenURI(tokenId, tokenUri); - emit Mint(to, tokenId, prompt, aigcData, uri, proof); + } + + /** + * @dev See {IERC7007-addAigcData}. + */ + function addAigcData( + uint256 tokenId, + bytes calldata prompt, + bytes calldata aigcData, + bytes calldata proof + ) public virtual override { + require(ownerOf(tokenId) != address(0), "ERC7007: nonexistent token"); + require(verify(prompt, aigcData, proof), "ERC7007: invalid proof"); + emit AigcData(tokenId, prompt, aigcData, proof); } /** diff --git a/assets/erc-7007/contracts/IERC7007.sol b/assets/erc-7007/contracts/IERC7007.sol index 6a86f49319..cdf800b6d1 100644 --- a/assets/erc-7007/contracts/IERC7007.sol +++ b/assets/erc-7007/contracts/IERC7007.sol @@ -9,34 +9,28 @@ import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; */ interface IERC7007 is IERC165, IERC721 { /** - * @dev Emitted when `tokenId` token is minted. + * @dev Emitted when AI Generated Content (AIGC) data is added to token at `tokenId`. */ - event Mint( - address indexed to, + event AigcData( uint256 indexed tokenId, bytes indexed prompt, bytes aigcData, - string uri, bytes proof ); /** - * @dev Mint token at `tokenId` given `to`, `prompt`, `aigcData`, `uri` and `proof`. `proof` means that we input the ZK proof when using zkML and byte zero when using opML as the verification method. - * - * Requirements: - * - `tokenId` must not exist.' - * - verify(`prompt`, `aigcData`, `proof`) must return true. + * @dev Add AIGC data to token at `tokenId` given `prompt`, `aigcData` and `proof`. * * Optional: * - `proof` should not include `aigcData` to save gas. + * - verify(`prompt`, `aigcData`, `proof`) should return true for zkML scenario. */ - function mint( - address to, + function addAigcData( + uint256 tokenId, bytes calldata prompt, bytes calldata aigcData, - string calldata uri, bytes calldata proof - ) external returns (uint256 tokenId); + ) external; /** * @dev Verify the `prompt`, `aigcData` and `proof`. diff --git a/assets/erc-7007/contracts/IERC7007Updatable.sol b/assets/erc-7007/contracts/IERC7007Updatable.sol index 1e1b0b11f8..bd9aa6bad9 100644 --- a/assets/erc-7007/contracts/IERC7007Updatable.sol +++ b/assets/erc-7007/contracts/IERC7007Updatable.sol @@ -12,8 +12,7 @@ interface IERC7007Updatable is IERC7007 { */ function update( bytes calldata prompt, - bytes calldata aigcData, - string calldata uri + bytes calldata aigcData ) external; /** @@ -22,7 +21,6 @@ interface IERC7007Updatable is IERC7007 { event Update( uint256 indexed tokenId, bytes indexed prompt, - bytes indexed aigcData, - string uri + bytes indexed aigcData ); } diff --git a/assets/erc-7007/package-lock.json b/assets/erc-7007/package-lock.json deleted file mode 100644 index db6776ab74..0000000000 --- a/assets/erc-7007/package-lock.json +++ /dev/null @@ -1,16534 +0,0 @@ -{ - "name": "erc7007", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "erc7007", - "version": "1.0.0", - "license": "ISC", - "devDependencies": { - "@nomicfoundation/hardhat-toolbox": "^2.0.2", - "@openzeppelin/contracts": "^4.8.3", - "hardhat": "^2.14.0" - } - }, - "node_modules/@chainsafe/as-sha256": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", - "integrity": "sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==", - "dev": true - }, - "node_modules/@chainsafe/persistent-merkle-tree": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz", - "integrity": "sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "node_modules/@chainsafe/ssz": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.9.4.tgz", - "integrity": "sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.4.2", - "case": "^1.6.3" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true, - "peer": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "peer": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@morgan-stanley/ts-mocking-bird": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@morgan-stanley/ts-mocking-bird/-/ts-mocking-bird-0.6.4.tgz", - "integrity": "sha512-57VJIflP8eR2xXa9cD1LUawh+Gh+BVQfVu0n6GALyg/AqV/Nz25kDRvws3i9kIe1PTrbsZZOYpsYp6bXPd6nVA==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.16", - "uuid": "^7.0.3" - }, - "peerDependencies": { - "jasmine": "2.x || 3.x || 4.x", - "jest": "26.x || 27.x || 28.x", - "typescript": ">=4.2" - }, - "peerDependenciesMeta": { - "jasmine": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "node_modules/@morgan-stanley/ts-mocking-bird/node_modules/uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", - "dev": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@noble/secp256k1": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", - "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nomicfoundation/ethereumjs-block": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz", - "integrity": "sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-block/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-blockchain": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz", - "integrity": "sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-ethash": "3.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "level": "^8.0.0", - "lru-cache": "^5.1.1", - "memory-level": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-blockchain/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-common": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz", - "integrity": "sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-util": "9.0.1", - "crc-32": "^1.2.0" - } - }, - "node_modules/@nomicfoundation/ethereumjs-ethash": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz", - "integrity": "sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-ethash/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-evm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz", - "integrity": "sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ==", - "dev": true, - "dependencies": { - "@ethersproject/providers": "^5.7.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-evm/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz", - "integrity": "sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ==", - "dev": true, - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-statemanager": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz", - "integrity": "sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1", - "js-sdsl": "^4.1.4" - } - }, - "node_modules/@nomicfoundation/ethereumjs-statemanager/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-trie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz", - "integrity": "sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@types/readable-stream": "^2.3.13", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-trie/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-tx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz", - "integrity": "sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w==", - "dev": true, - "dependencies": { - "@chainsafe/ssz": "^0.9.2", - "@ethersproject/providers": "^5.7.2", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz", - "integrity": "sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA==", - "dev": true, - "dependencies": { - "@chainsafe/ssz": "^0.10.0", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util/node_modules/@chainsafe/persistent-merkle-tree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz", - "integrity": "sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util/node_modules/@chainsafe/ssz": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.10.2.tgz", - "integrity": "sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==", - "dev": true, - "dependencies": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.5.0" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/ethereumjs-vm": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz", - "integrity": "sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-vm/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/hardhat-chai-matchers": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz", - "integrity": "sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@types/chai-as-promised": "^7.1.3", - "chai-as-promised": "^7.1.1", - "deep-eql": "^4.0.1", - "ordinal": "^1.0.3" - }, - "peerDependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.0", - "chai": "^4.2.0", - "ethers": "^5.0.0", - "hardhat": "^2.9.4" - } - }, - "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz", - "integrity": "sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==", - "dev": true, - "peer": true, - "dependencies": { - "ethereumjs-util": "^7.1.4" - }, - "peerDependencies": { - "hardhat": "^2.9.5" - } - }, - "node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@nomicfoundation/hardhat-toolbox": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.2.tgz", - "integrity": "sha512-vnN1AzxbvpSx9pfdRHbUzTRIXpMLPXnUlkW855VaDk6N1pwRaQ2gNzEmFAABk4lWf11E00PKwFd/q27HuwYrYg==", - "dev": true, - "peerDependencies": { - "@ethersproject/abi": "^5.4.7", - "@ethersproject/providers": "^5.4.7", - "@nomicfoundation/hardhat-chai-matchers": "^1.0.0", - "@nomicfoundation/hardhat-network-helpers": "^1.0.0", - "@nomiclabs/hardhat-ethers": "^2.0.0", - "@nomiclabs/hardhat-etherscan": "^3.0.0", - "@typechain/ethers-v5": "^10.1.0", - "@typechain/hardhat": "^6.1.2", - "@types/chai": "^4.2.0", - "@types/mocha": ">=9.1.0", - "@types/node": ">=12.0.0", - "chai": "^4.2.0", - "ethers": "^5.4.7", - "hardhat": "^2.11.0", - "hardhat-gas-reporter": "^1.0.8", - "solidity-coverage": "^0.8.1", - "ts-node": ">=8.0.0", - "typechain": "^8.1.0", - "typescript": ">=4.5.0" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", - "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", - "dev": true, - "engines": { - "node": ">= 12" - }, - "optionalDependencies": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.1", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.1" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", - "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", - "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", - "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", - "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", - "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", - "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", - "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", - "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", - "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", - "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomiclabs/hardhat-ethers": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz", - "integrity": "sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==", - "dev": true, - "peer": true, - "peerDependencies": { - "ethers": "^5.0.0", - "hardhat": "^2.0.0" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz", - "integrity": "sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^8.1.0", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.14.0" - }, - "peerDependencies": { - "hardhat": "^2.0.4" - } - }, - "node_modules/@openzeppelin/contracts": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.3.tgz", - "integrity": "sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==", - "dev": true - }, - "node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, - "dependencies": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, - "dependencies": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, - "dependencies": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@solidity-parser/parser": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", - "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", - "dev": true, - "peer": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "peer": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "peer": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "peer": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true, - "peer": true - }, - "node_modules/@typechain/ethers-v5": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz", - "integrity": "sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" - }, - "peerDependencies": { - "@ethersproject/abi": "^5.0.0", - "@ethersproject/bytes": "^5.0.0", - "@ethersproject/providers": "^5.0.0", - "ethers": "^5.1.3", - "typechain": "^8.1.1", - "typescript": ">=4.3.0" - } - }, - "node_modules/@typechain/hardhat": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-6.1.5.tgz", - "integrity": "sha512-lg7LW4qDZpxFMknp3Xool61Fg6Lays8F8TXdFGBG+MxyYcYU5795P1U2XdStuzGq9S2Dzdgh+1jGww9wvZ6r4Q==", - "dev": true, - "peer": true, - "dependencies": { - "fs-extra": "^9.1.0" - }, - "peerDependencies": { - "@ethersproject/abi": "^5.4.7", - "@ethersproject/providers": "^5.4.7", - "@typechain/ethers-v5": "^10.2.0", - "ethers": "^5.4.7", - "hardhat": "^2.9.9", - "typechain": "^8.1.1" - } - }, - "node_modules/@typechain/hardhat/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "peer": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typechain/hardhat/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "peer": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@typechain/hardhat/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true, - "peer": true - }, - "node_modules/@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/chai": "*" - } - }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "peer": true - }, - "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true, - "peer": true - }, - "node_modules/@types/node": { - "version": "18.16.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", - "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==", - "dev": true - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true, - "peer": true - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true, - "peer": true - }, - "node_modules/@types/readable-stream": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", - "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true, - "peer": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true, - "engines": { - "node": ">=0.3.0" - } - }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true, - "peer": true - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "peer": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true, - "peer": true - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "peer": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true, - "peer": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "peer": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true, - "peer": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "peer": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "peer": true - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "node_modules/bigint-crypto-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.2.2.tgz", - "integrity": "sha512-U1RbE3aX9ayCUVcIPHuPDPKcK3SFOXf93J1UK/iHlJuQB7bhagPIX06/CLpLEsDThJ7KA4Dhrnzynl+d2weTiw==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dev": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dev": true, - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "peer": true - }, - "node_modules/catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "peer": true, - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": true, - "peer": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "peer": true, - "dependencies": { - "check-error": "^1.0.2" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 5" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/classic-level": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", - "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "^2.2.2", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "peer": true, - "dependencies": { - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "colors": "^1.1.2" - } - }, - "node_modules/cli-table3/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "peer": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-table3/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "peer": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "node_modules/command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/command-line-usage": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", - "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^4.0.2", - "chalk": "^2.4.2", - "table-layout": "^1.0.2", - "typical": "^5.2.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/command-line-usage/node_modules/array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/command-line-usage/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "peer": true, - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "peer": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "peer": true - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "peer": true - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true, - "peer": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "peer": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "peer": true - }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "peer": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, - "peer": true, - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, - "peer": true, - "dependencies": { - "heap": ">= 0.2.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "peer": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "peer": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", - "dev": true, - "peer": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-abstract/node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true, - "peer": true - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "peer": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "peer": true, - "dependencies": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=0.12.0" - }, - "optionalDependencies": { - "source-map": "~0.2.0" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "peerDependencies": { - "@codechecks/client": "^0.1.0" - }, - "peerDependenciesMeta": { - "@codechecks/client": { - "optional": true - } - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/eth-gas-reporter/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "peer": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "peer": true, - "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "peer": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eth-gas-reporter/node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "peer": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eth-gas-reporter/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eth-gas-reporter/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "peer": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/eth-gas-reporter/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eth-gas-reporter/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "peer": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "peer": true, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/eth-gas-reporter/node_modules/scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "peer": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/eth-gas-reporter/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "peer": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "peer": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "peer": true, - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" - } - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ethereumjs-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, - "peer": true, - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "peer": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "peer": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "peer": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "peer": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "peer": true - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "peer": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^3.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "peer": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "peer": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true, - "peer": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "peer": true, - "dependencies": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "bin": { - "testrpc-sc": "index.js" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "peer": true, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "peer": true, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "peer": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "peer": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "peer": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.14.0.tgz", - "integrity": "sha512-73jsInY4zZahMSVFurSK+5TNCJTXMv+vemvGia0Ac34Mm19fYp6vEPVGF3sucbumszsYxiTT2TbS8Ii2dsDSoQ==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@nomicfoundation/ethereumjs-vm": "7.0.1", - "@nomicfoundation/solidity-analyzer": "^0.1.0", - "@sentry/node": "^5.18.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "mnemonist": "^0.38.0", - "mocha": "^10.0.0", - "p-map": "^4.0.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tsort": "0.0.1", - "undici": "^5.14.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "bin": { - "hardhat": "internal/cli/bootstrap.js" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", - "dev": true, - "peer": true, - "dependencies": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - }, - "peerDependencies": { - "hardhat": "^2.0.2" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "peer": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true, - "peer": true - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "peer": true, - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true, - "peer": true - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", - "dev": true - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "peer": true - }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "dependencies": { - "fp-ts": "^1.0.0" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "peer": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "peer": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "peer": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "peer": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "peer": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "peer": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "peer": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "peer": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "peer": true - }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "peer": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "peer": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "peer": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "peer": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dev": true, - "dependencies": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/level" - } - }, - "node_modules/level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "peer": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true, - "peer": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "peer": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "peer": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "peer": true - }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true, - "peer": true - }, - "node_modules/mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/memory-level": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", - "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", - "dev": true, - "dependencies": { - "abstract-level": "^1.0.0", - "functional-red-black-tree": "^1.0.1", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "peer": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "peer": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "peer": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "dependencies": { - "obliterator": "^2.0.0" - } - }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-macros": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", - "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "peer": true, - "dependencies": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node_modules/node-environment-flags/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "dev": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "peer": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "peer": true, - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "peer": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", - "dev": true, - "peer": true, - "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "peer": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ordinal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", - "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", - "dev": true, - "peer": true - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true, - "peer": true - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "peer": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "peer": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "peer": true - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dev": true, - "peer": true, - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "peer": true - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", - "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "peer": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, - "peer": true, - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/reduce-flatten": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", - "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "peer": true, - "dependencies": { - "req-from": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "peer": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "peer": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dev": true, - "peer": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "peer": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "peer": true - }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "peer": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peer": true, - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, - "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "peer": true, - "dependencies": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "istanbul": "lib/cli.js" - } - }, - "node_modules/sc-istanbul/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/sc-istanbul/node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "peer": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sc-istanbul/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true, - "peer": true - }, - "node_modules/sc-istanbul/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "peer": true - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "peer": true, - "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "peer": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true - }, - "node_modules/solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/solc/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solidity-coverage": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", - "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "difflib": "^0.2.4", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "mocha": "7.1.2", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.6" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - }, - "peerDependencies": { - "hardhat": "^2.11.0" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/solidity-coverage/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "peer": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "peer": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/solidity-coverage/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/solidity-coverage/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true, - "peer": true - }, - "node_modules/solidity-coverage/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "peer": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/solidity-coverage/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/solidity-coverage/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/solidity-coverage/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/solidity-coverage/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/solidity-coverage/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "peer": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/solidity-coverage/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solidity-coverage/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/solidity-coverage/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "peer": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/solidity-coverage/node_modules/mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/solidity-coverage/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "peer": true - }, - "node_modules/solidity-coverage/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/solidity-coverage/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "peer": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "peer": true, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solidity-coverage/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true - }, - "node_modules/solidity-coverage/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, - "node_modules/solidity-coverage/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "peer": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "peer": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "peer": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "peer": true - }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "peer": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "peer": true - }, - "node_modules/stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/string-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", - "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", - "dev": true, - "peer": true - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "peer": true, - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "peer": true, - "dependencies": { - "get-port": "^3.1.0" - } - }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, - "peer": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table-layout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", - "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", - "dev": true, - "peer": true, - "dependencies": { - "array-back": "^4.0.1", - "deep-extend": "~0.6.0", - "typical": "^5.2.0", - "wordwrapjs": "^4.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/table-layout/node_modules/array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table-layout/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true - }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "peer": true, - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true, - "peer": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "peer": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ts-command-line-args": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.0.tgz", - "integrity": "sha512-Ff7Xt04WWCjj/cmPO9eWTJX3qpBZWuPWyQYG1vnxJao+alWWYjwJBc5aYz3h5p5dE08A6AnpkgiCtP/0KXXBYw==", - "dev": true, - "peer": true, - "dependencies": { - "@morgan-stanley/ts-mocking-bird": "^0.6.2", - "chalk": "^4.1.0", - "command-line-args": "^5.1.1", - "command-line-usage": "^6.1.0", - "string-format": "^2.0.0" - }, - "bin": { - "write-markdown": "dist/write-markdown.js" - } - }, - "node_modules/ts-command-line-args/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ts-command-line-args/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ts-command-line-args/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ts-command-line-args/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true - }, - "node_modules/ts-command-line-args/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-command-line-args/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "peer": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typechain": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.1.1.tgz", - "integrity": "sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/prettier": "^2.1.1", - "debug": "^4.3.1", - "fs-extra": "^7.0.0", - "glob": "7.1.7", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.3.1", - "ts-command-line-args": "^2.2.0", - "ts-essentials": "^7.0.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - }, - "peerDependencies": { - "typescript": ">=4.3.0" - } - }, - "node_modules/typechain/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typechain/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "peer": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "peer": true - }, - "node_modules/typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.0.tgz", - "integrity": "sha512-fR9RXCc+6Dxav4P9VV/sp5w3eFiSdOjJYsbtWfd4s5L5C4ogyuVpdKIVHeW0vV1MloM65/f7W45nR9ZxwVdyiA==", - "dev": true, - "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "peer": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true, - "peer": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "peer": true - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/web3-utils": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.9.0.tgz", - "integrity": "sha512-p++69rCNNfu2jM9n5+VD/g26l+qkEOQ1m6cfRQCbH8ZRrtquTmrirJMgTmyOoax5a5XRYOuws14aypCOs51pdQ==", - "dev": true, - "peer": true, - "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/web3-utils/node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "peer": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, - "peer": true - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "peer": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "peer": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "peer": true - }, - "node_modules/wordwrapjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", - "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", - "dev": true, - "peer": true, - "dependencies": { - "reduce-flatten": "^2.0.0", - "typical": "^5.2.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/wordwrapjs/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@chainsafe/as-sha256": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", - "integrity": "sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==", - "dev": true - }, - "@chainsafe/persistent-merkle-tree": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz", - "integrity": "sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "@chainsafe/ssz": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.9.4.tgz", - "integrity": "sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.4.2", - "case": "^1.6.3" - } - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "peer": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true - }, - "@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - }, - "dependencies": { - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "requires": {} - } - } - }, - "@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "dev": true, - "requires": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "peer": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true, - "peer": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "peer": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - } - }, - "@morgan-stanley/ts-mocking-bird": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@morgan-stanley/ts-mocking-bird/-/ts-mocking-bird-0.6.4.tgz", - "integrity": "sha512-57VJIflP8eR2xXa9cD1LUawh+Gh+BVQfVu0n6GALyg/AqV/Nz25kDRvws3i9kIe1PTrbsZZOYpsYp6bXPd6nVA==", - "dev": true, - "peer": true, - "requires": { - "lodash": "^4.17.16", - "uuid": "^7.0.3" - }, - "dependencies": { - "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", - "dev": true, - "peer": true - } - } - }, - "@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true - }, - "@noble/secp256k1": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", - "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "peer": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "peer": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "peer": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@nomicfoundation/ethereumjs-block": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz", - "integrity": "sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-blockchain": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz", - "integrity": "sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-ethash": "3.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "level": "^8.0.0", - "lru-cache": "^5.1.1", - "memory-level": "^1.0.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-common": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz", - "integrity": "sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-util": "9.0.1", - "crc-32": "^1.2.0" - } - }, - "@nomicfoundation/ethereumjs-ethash": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz", - "integrity": "sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-evm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz", - "integrity": "sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ==", - "dev": true, - "requires": { - "@ethersproject/providers": "^5.7.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz", - "integrity": "sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ==", - "dev": true - }, - "@nomicfoundation/ethereumjs-statemanager": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz", - "integrity": "sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1", - "js-sdsl": "^4.1.4" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-trie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz", - "integrity": "sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@types/readable-stream": "^2.3.13", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-tx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz", - "integrity": "sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w==", - "dev": true, - "requires": { - "@chainsafe/ssz": "^0.9.2", - "@ethersproject/providers": "^5.7.2", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-util": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz", - "integrity": "sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA==", - "dev": true, - "requires": { - "@chainsafe/ssz": "^0.10.0", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "ethereum-cryptography": "0.1.3" - }, - "dependencies": { - "@chainsafe/persistent-merkle-tree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz", - "integrity": "sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "@chainsafe/ssz": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.10.2.tgz", - "integrity": "sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.5.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/ethereumjs-vm": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz", - "integrity": "sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "@nomicfoundation/hardhat-chai-matchers": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz", - "integrity": "sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ==", - "dev": true, - "peer": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@types/chai-as-promised": "^7.1.3", - "chai-as-promised": "^7.1.1", - "deep-eql": "^4.0.1", - "ordinal": "^1.0.3" - } - }, - "@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz", - "integrity": "sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==", - "dev": true, - "peer": true, - "requires": { - "ethereumjs-util": "^7.1.4" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "peer": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "peer": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "@nomicfoundation/hardhat-toolbox": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.2.tgz", - "integrity": "sha512-vnN1AzxbvpSx9pfdRHbUzTRIXpMLPXnUlkW855VaDk6N1pwRaQ2gNzEmFAABk4lWf11E00PKwFd/q27HuwYrYg==", - "dev": true, - "requires": {} - }, - "@nomicfoundation/solidity-analyzer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", - "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", - "dev": true, - "requires": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.1", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.1" - } - }, - "@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", - "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", - "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", - "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", - "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", - "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", - "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", - "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", - "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", - "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", - "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", - "dev": true, - "optional": true - }, - "@nomiclabs/hardhat-ethers": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz", - "integrity": "sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==", - "dev": true, - "peer": true, - "requires": {} - }, - "@nomiclabs/hardhat-etherscan": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz", - "integrity": "sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ==", - "dev": true, - "peer": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^8.1.0", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.14.0" - } - }, - "@openzeppelin/contracts": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.3.tgz", - "integrity": "sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==", - "dev": true - }, - "@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true - }, - "@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, - "requires": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" - } - }, - "@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, - "requires": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" - } - }, - "@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, - "requires": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - } - }, - "@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true - }, - "@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@solidity-parser/parser": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", - "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", - "dev": true, - "peer": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "peer": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "peer": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "peer": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true, - "peer": true - }, - "@typechain/ethers-v5": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz", - "integrity": "sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w==", - "dev": true, - "peer": true, - "requires": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" - } - }, - "@typechain/hardhat": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-6.1.5.tgz", - "integrity": "sha512-lg7LW4qDZpxFMknp3Xool61Fg6Lays8F8TXdFGBG+MxyYcYU5795P1U2XdStuzGq9S2Dzdgh+1jGww9wvZ6r4Q==", - "dev": true, - "peer": true, - "requires": { - "fs-extra": "^9.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "peer": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "peer": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "peer": true - } - } - }, - "@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true, - "peer": true - }, - "@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", - "dev": true, - "peer": true, - "requires": { - "@types/chai": "*" - } - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "peer": true, - "requires": { - "@types/node": "*" - } - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "peer": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "peer": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "peer": true - }, - "@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true, - "peer": true - }, - "@types/node": { - "version": "18.16.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", - "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==", - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true, - "peer": true - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true, - "peer": true - }, - "@types/readable-stream": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", - "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", - "dev": true, - "requires": { - "@types/node": "*", - "safe-buffer": "~5.1.1" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true, - "peer": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - } - }, - "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "peer": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "peer": true - }, - "address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "dev": true, - "peer": true - }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "peer": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true, - "peer": true - }, - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true, - "peer": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "peer": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "peer": true - }, - "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "peer": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "peer": true - }, - "array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true, - "peer": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "peer": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "peer": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "peer": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "peer": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true, - "peer": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "peer": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "peer": true - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "peer": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "peer": true - }, - "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true, - "peer": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "peer": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "peer": true - } - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "bigint-crypto-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.2.2.tgz", - "integrity": "sha512-U1RbE3aX9ayCUVcIPHuPDPKcK3SFOXf93J1UK/iHlJuQB7bhagPIX06/CLpLEsDThJ7KA4Dhrnzynl+d2weTiw==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dev": true, - "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dev": true, - "requires": { - "streamsearch": "^1.1.0" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "peer": true - }, - "catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "dev": true - }, - "cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "peer": true, - "requires": { - "nofilter": "^3.1.0" - } - }, - "chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": true, - "peer": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "peer": true, - "requires": { - "check-error": "^1.0.2" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true, - "peer": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "peer": true - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "classic-level": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", - "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", - "dev": true, - "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "^2.2.2", - "node-gyp-build": "^4.3.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "peer": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "peer": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "peer": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "peer": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, - "peer": true, - "requires": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - } - }, - "command-line-usage": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", - "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", - "dev": true, - "peer": true, - "requires": { - "array-back": "^4.0.2", - "chalk": "^2.4.2", - "table-layout": "^1.0.2", - "typical": "^5.2.0" - }, - "dependencies": { - "array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "peer": true - }, - "typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true - } - } - }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "peer": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "peer": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "peer": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "peer": true - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "peer": true - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true, - "peer": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "peer": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true, - "peer": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "peer": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "peer": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "peer": true - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "peer": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "peer": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, - "peer": true, - "requires": { - "address": "^1.0.1", - "debug": "4" - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, - "peer": true, - "requires": { - "heap": ">= 0.2.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "peer": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "peer": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", - "dev": true, - "peer": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" - }, - "dependencies": { - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - } - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true, - "peer": true - }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "peer": true, - "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "peer": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "peer": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, - "peer": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, - "peer": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "peer": true - }, - "eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": true, - "peer": true, - "requires": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "peer": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "peer": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "peer": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "peer": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "peer": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "peer": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true, - "peer": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "peer": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "peer": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "peer": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true, - "peer": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "peer": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true, - "peer": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "peer": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "peer": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "peer": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "peer": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "peer": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "peer": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "peer": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true, - "peer": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "dev": true, - "peer": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "peer": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "peer": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "peer": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "peer": true, - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, - "requires": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - } - } - }, - "ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, - "peer": true, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "peer": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "peer": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "peer": true - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "peer": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "peer": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "peer": true - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "peer": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dev": true, - "peer": true, - "requires": { - "array-back": "^3.0.1" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "peer": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "peer": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "peer": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true, - "peer": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "peer": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "peer": true - }, - "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, - "peer": true - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "peer": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "peer": true, - "requires": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "peer": true, - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "peer": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "peer": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "peer": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "peer": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "peer": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "peer": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "peer": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "peer": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "hardhat": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.14.0.tgz", - "integrity": "sha512-73jsInY4zZahMSVFurSK+5TNCJTXMv+vemvGia0Ac34Mm19fYp6vEPVGF3sucbumszsYxiTT2TbS8Ii2dsDSoQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@nomicfoundation/ethereumjs-vm": "7.0.1", - "@nomicfoundation/solidity-analyzer": "^0.1.0", - "@sentry/node": "^5.18.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "mnemonist": "^0.38.0", - "mocha": "^10.0.0", - "p-map": "^4.0.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tsort": "0.0.1", - "undici": "^5.14.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - } - }, - "hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", - "dev": true, - "peer": true, - "requires": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "peer": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "peer": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "peer": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "peer": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true, - "peer": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "peer": true, - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "peer": true, - "requires": { - "@types/node": "^10.0.3" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true, - "peer": true - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "peer": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "peer": true - }, - "immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "peer": true - }, - "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "peer": true, - "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "peer": true - }, - "io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "requires": { - "fp-ts": "^1.0.0" - } - }, - "is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - } - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "peer": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "peer": true - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "peer": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "peer": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "peer": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "peer": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "peer": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "peer": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "peer": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "peer": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "peer": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "peer": true - }, - "js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "peer": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "peer": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "peer": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "peer": true - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "peer": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "peer": true - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dev": true, - "requires": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - } - }, - "level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "dev": true - }, - "level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "peer": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true, - "peer": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "peer": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "peer": true, - "requires": { - "get-func-name": "^2.0.0" - } - }, - "lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "peer": true - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true, - "peer": true - }, - "mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-level": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", - "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", - "dev": true, - "requires": { - "abstract-level": "^1.0.0", - "functional-red-black-tree": "^1.0.1", - "module-error": "^1.0.1" - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "peer": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "peer": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "peer": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "peer": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "peer": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "peer": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "requires": { - "obliterator": "^2.0.0" - } - }, - "mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "requires": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, - "napi-macros": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", - "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "peer": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "peer": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true - } - } - }, - "node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "dev": true - }, - "nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, - "peer": true - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "peer": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "peer": true, - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "peer": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "peer": true - }, - "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "peer": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "peer": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", - "dev": true, - "peer": true, - "requires": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" - } - }, - "obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "peer": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "ordinal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", - "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", - "dev": true, - "peer": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true, - "peer": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "peer": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "peer": true - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "peer": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "peer": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "peer": true - }, - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "peer": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "peer": true - }, - "promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dev": true, - "peer": true, - "requires": { - "asap": "~2.0.6" - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "peer": true - }, - "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "peer": true - }, - "qs": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", - "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "peer": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, - "peer": true, - "requires": { - "minimatch": "^3.0.5" - } - }, - "reduce-flatten": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", - "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", - "dev": true, - "peer": true - }, - "regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - } - }, - "req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "peer": true, - "requires": { - "req-from": "^2.0.0" - } - }, - "req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "peer": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "peer": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "peer": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "peer": true - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "peer": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "peer": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "peer": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "peer": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "peer": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "requires": { - "bn.js": "^5.2.0" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "peer": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, - "safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "peer": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "peer": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "peer": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true - } - } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "peer": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "peer": true, - "requires": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - } - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "peer": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "peer": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "peer": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "peer": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true - } - } - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "solidity-coverage": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", - "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", - "dev": true, - "peer": true, - "requires": { - "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "difflib": "^0.2.4", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "mocha": "7.1.2", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.6" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "peer": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "peer": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "peer": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "peer": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "peer": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "peer": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true, - "peer": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "peer": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "peer": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "peer": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true, - "peer": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "peer": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "peer": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", - "dev": true, - "peer": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "peer": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "peer": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "peer": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "peer": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", - "dev": true, - "peer": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "peer": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "peer": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "peer": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "peer": true - }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "peer": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "peer": true - } - } - }, - "stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, - "requires": { - "type-fest": "^0.7.1" - }, - "dependencies": { - "type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true - } - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true, - "peer": true - }, - "streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "string-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", - "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "peer": true, - "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - } - }, - "sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "peer": true, - "requires": { - "get-port": "^3.1.0" - } - }, - "table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, - "peer": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "peer": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true - } - } - }, - "table-layout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", - "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", - "dev": true, - "peer": true, - "requires": { - "array-back": "^4.0.1", - "deep-extend": "~0.6.0", - "typical": "^5.2.0", - "wordwrapjs": "^4.0.0" - }, - "dependencies": { - "array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "peer": true - }, - "typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true - } - } - }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "peer": true, - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true, - "peer": true - } - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "peer": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "ts-command-line-args": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.0.tgz", - "integrity": "sha512-Ff7Xt04WWCjj/cmPO9eWTJX3qpBZWuPWyQYG1vnxJao+alWWYjwJBc5aYz3h5p5dE08A6AnpkgiCtP/0KXXBYw==", - "dev": true, - "peer": true, - "requires": { - "@morgan-stanley/ts-mocking-bird": "^0.6.2", - "chalk": "^4.1.0", - "command-line-args": "^5.1.1", - "command-line-usage": "^6.1.0", - "string-format": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "peer": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "peer": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "peer": true, - "requires": {} - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "peer": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "peer": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "peer": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "peer": true - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - }, - "typechain": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.1.1.tgz", - "integrity": "sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ==", - "dev": true, - "peer": true, - "requires": { - "@types/prettier": "^2.1.1", - "debug": "^4.3.1", - "fs-extra": "^7.0.0", - "glob": "7.1.7", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.3.1", - "ts-command-line-args": "^2.2.0", - "ts-essentials": "^7.0.1" - }, - "dependencies": { - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "peer": true - } - } - }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "peer": true - }, - "typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", - "dev": true, - "peer": true - }, - "typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, - "peer": true - }, - "uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "peer": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "undici": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.0.tgz", - "integrity": "sha512-fR9RXCc+6Dxav4P9VV/sp5w3eFiSdOjJYsbtWfd4s5L5C4ogyuVpdKIVHeW0vV1MloM65/f7W45nR9ZxwVdyiA==", - "dev": true, - "requires": { - "busboy": "^1.6.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "peer": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true, - "peer": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "peer": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "peer": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3-utils": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.9.0.tgz", - "integrity": "sha512-p++69rCNNfu2jM9n5+VD/g26l+qkEOQ1m6cfRQCbH8ZRrtquTmrirJMgTmyOoax5a5XRYOuws14aypCOs51pdQ==", - "dev": true, - "peer": true, - "requires": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "dependencies": { - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "peer": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "peer": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "peer": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "peer": true, - "requires": { - "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" - } - }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, - "peer": true - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "peer": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "peer": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "peer": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "peer": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "peer": true - }, - "wordwrapjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", - "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", - "dev": true, - "peer": true, - "requires": { - "reduce-flatten": "^2.0.0", - "typical": "^5.2.0" - }, - "dependencies": { - "typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, - "peer": true - } - } - }, - "workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true, - "peer": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "peer": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/assets/erc-7007/test/test.js b/assets/erc-7007/test/test.js index 4728191951..9bfca6e04f 100644 --- a/assets/erc-7007/test/test.js +++ b/assets/erc-7007/test/test.js @@ -46,11 +46,11 @@ describe("ERC7007Zkml.sol", function () { await expect(erc7007.mint(owner.address, prompt, aigcData, uri, validProof)).to.be.revertedWith("ERC721: token already minted"); }); - it("should emit a Mint event", async function () { + it("should emit a AigcData event", async function () { const erc7007 = await deployERC7007Fixture(); const [owner] = await ethers.getSigners(); await expect(erc7007.mint(owner.address, prompt, aigcData, uri, validProof)) - .to.emit(erc7007, "Mint") + .to.emit(erc7007, "AigcData") }); }); @@ -130,11 +130,11 @@ describe("ERC7007Opml.sol", function () { await expect(erc7007.mint(owner.address, prompt, aigcData, uri, 0x00)).to.be.revertedWith("ERC721: token already minted"); }); - it("should emit a Mint event", async function () { + it("should emit a AigcData event", async function () { const erc7007 = await deployERC7007Fixture(); const [owner] = await ethers.getSigners(); await expect(erc7007.mint(owner.address, prompt, aigcData, uri, validProof)) - .to.emit(erc7007, "Mint") + .to.emit(erc7007, "AigcData") }); }); From e84ee2b9506ce7dd20d1edf5c902c41fa0128d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Cuesta=20Ca=C3=B1ada?= <38806121+alcueca@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:25:33 +0100 Subject: [PATCH 32/79] Add ERC: Common Quote Oracle Merged by EIP-Bot. --- ERCS/erc-7726.md | 134 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 ERCS/erc-7726.md diff --git a/ERCS/erc-7726.md b/ERCS/erc-7726.md new file mode 100644 index 0000000000..85c4fec7c5 --- /dev/null +++ b/ERCS/erc-7726.md @@ -0,0 +1,134 @@ +--- +eip: 7726 +title: Common Quote Oracle +description: Interface for data feeds providing the relative value of assets. +author: alcueca (@alcueca), ruvaag (@ruvaag), totomanov (@totomanov), r0ohafza (@r0ohafza) +discussions-to: https://ethereum-magicians.org/t/erc-7726-common-quote-oracle/20351 +status: Draft +type: Standards Track +category: ERC +created: 2024-06-20 +requires: 7528 +--- + +## Abstract + +The following allows for the implementation of a standard API for data feeds providing the relative value of +assets, forcing compliant contracts to use explicit token amounts instead of price factors. This approach has been +shown to lead to better security and time-to-market outcomes. + +## Motivation + +The information required to value assets is scattered over a number of major and minor sources, each one with their own +integration API and security considerations. Many protocols over the years have implemented oracle adapter layers for +their own use to abstract this complexity away from their core implementations, leading to much duplicated effort. + +This specification provides a standard API aimed to serve the majority of use cases. Preference is given to ease of +integration and serving the needs of product teams with less knowledge, requirements and resources. + +## Specification +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. +### Definitions + +- base asset: The asset that the user needs to know the value for (e.g: USDC as in "I need to know the value of 1e6 USDC + in ETH terms"). +- quote asset: The asset in which the user needs to value the `base` (e.g: ETH as in "I need to know the value of 1e6 + USDC in ETH terms"). +- value: An amount of `base` in `quote` terms (e.g. The `value` of 1000e6 USDC in ETH terms is 283,969,794,427,307,000 + ETH, and the `value` of 1000e18 ETH in USDC terms is 3,521,501,299,000 USDC). Note that this is an asset amount, and + not a decimal factor. + +### Methods + +#### `getQuote` + +Returns the value of `baseAmount` of `base` in `quote` terms. + +MUST round down towards 0. + +MUST revert with `OracleUnsupportedPair` if not capable to provide data for the specified `base` and `quote` pair. + +MUST revert with `OracleUntrustedData` if not capable to provide data within a degree of confidence publicly specified. + +MUST revert if the value of `baseAmount` of `base` in `quote` terms would overflow in a uint256. + +```yaml +- name: getQuote + type: function + stateMutability: view + + inputs: + - name: baseAmount + type: uint256 + - name: base + type: address + - name: quote + type: address + + outputs: + - name: quoteAmount + type: uint256 +``` + +### Special Addresses + +Some assets under the scope of this specification don't have an address, such as ETH, BTC and national currencies. + +For ETH, the address will be `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` as per [ERC-7528](./eip-7528.md). + +For BTC, the address will be `0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB`. + +For assets without an address, but with an ISO 4217 code, the code will be used (e.g. `address(840)` for USD). + +### Errors + +#### OracleUnsupportedPair + +```yaml +- name: OracleUnsupportedPair + type: error + + inputs: + - name: base + type: address + - name: quote + type: address +``` + +#### OracleUntrustedData + +```yaml +- name: OracleUntrustedData + type: error + + inputs: + - name: base + type: address + - name: quote + type: address +``` + +## Rationale + +The use of `getQuote` doesn't require the consumer to be aware of any decimal partitions that might have been defined +for the `base` or `quote` and should be preferred in most data processing cases. + +The spec doesn't include a `getPrice` function because it is rarely needed on-chain, and it would be a decimal number of +difficult representation. The popular option for representing prices can be implemented for [ERC-20](./eip-20.md) with decimals as +`oracle.getQuote(base, quote, 10\*\*base.decimals()) and will give the value of a whole unit of base in quote terms. + +## Backwards Compatibility + +Most existing data feeds related to the relative value of pairs of assets should be representable using this standard. + +## Security Considerations + +This specification purposefully provides no methods for data consumers to assess the validity of the data they receive. +It is expected of individual implementations using this specification to decide and publish the quality of the data that +they provide, including the conditions in which they will stop providing it. + +Consumers should review these guarantees and use them to decide whether to integrate or not with a data provider. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 6e77de4fc2636e9f5ef5720f829cbc85f18a93e8 Mon Sep 17 00:00:00 2001 From: Lukas <36800180+lukasrosario@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:22:35 -0700 Subject: [PATCH 33/79] Update ERC-7677: Move to Last Call Merged by EIP-Bot. --- ERCS/erc-7677.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7677.md b/ERCS/erc-7677.md index 8f49665cb6..3bd5cfdf6a 100644 --- a/ERCS/erc-7677.md +++ b/ERCS/erc-7677.md @@ -4,7 +4,8 @@ title: Paymaster Web Service Capability description: A way for apps to communicate with smart wallets about paymaster web services author: Lukas Rosario (@lukasrosario), Dror Tirosh (@drortirosh), Wilson Cusack (@wilsoncusack), Kristof Gazso (@kristofgazso), Hazim Jumali (@hazim-j) discussions-to: https://ethereum-magicians.org/t/erc-7677-paymaster-web-service-capability/19530 -status: Review +status: Last Call +last-call-deadline: 2024-09-05 type: Standards Track category: ERC created: 2024-04-03 From 9d46ca6d3206171f371f9cf259c6687026aa8db2 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Wed, 21 Aug 2024 23:42:38 -0400 Subject: [PATCH 34/79] CI: Update stale.yml Merged by EIP-Bot. --- .github/workflows/stale.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index a96921d17a..f298015cc7 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -20,16 +20,16 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} ascending: true # Since we have so many issues, the stale bot finds it hard to keep track. This makes sure that at least the oldest are removed. # Issue config - stale-issue-message: There has been no activity on this issue for 1 week. It will be closed after 3 months of inactivity. + stale-issue-message: There has been no activity on this issue for six months. It will be closed in 7 days if there is no new activity. close-issue-message: This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback. - days-before-issue-stale: 7 - days-before-issue-close: 49 # 49 + 7 weeks = 3 months + days-before-issue-stale: 183 + days-before-issue-close: 190 exempt-issue-labels: discussions-to stale-issue-label: w-stale # PR config - stale-pr-message: There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review. + stale-pr-message: There has been no activity on this issue for six months. It will be closed in 7 days if there is no new activity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review. close-pr-message: This pull request was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment. - days-before-pr-stale: 14 - days-before-pr-close: 42 # 42 + 14 weeks = 3 months + days-before-pr-stale: 183 + days-before-pr-close: 190 exempt-pr-milestones: "Manual Merge Queue" stale-pr-label: w-stale From 4a5445f31e3c8168f9619ed826c7bfabdc90c45a Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 24 Aug 2024 14:28:26 +0200 Subject: [PATCH 35/79] Update ERC-7579: fix typo Merged by EIP-Bot. --- ERCS/erc-7579.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7579.md b/ERCS/erc-7579.md index 02a467b8f6..2f3542e23c 100644 --- a/ERCS/erc-7579.md +++ b/ERCS/erc-7579.md @@ -93,7 +93,7 @@ function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) The execution mode is a `bytes32` value that is structured as follows: -- callType (1 byte): `0x00` for a single `call`, `0x01` for a batch `call` and `0xff` for `delegatecall` +- callType (1 byte): `0x00` for a single `call`, `0x01` for a batch `call`, `0xfe` for `staticcall` and `0xff` for `delegatecall` - execType (1 byte): `0x00` for executions that revert on failure, `0x01` for executions that do not revert on failure but implement some form of error handling - unused (4 bytes): this range is reserved for future standardization - modeSelector (4 bytes): an additional mode selector that can be used to create further execution modes @@ -105,7 +105,7 @@ Here is a visual representation of the execution mode: | -------- | -------- | ------- | ------------ | ----------- | | 1 byte | 1 byte | 4 bytes | 4 bytes | 22 bytes | -Accounts are NOT REQUIRED to implement all execution modes. The account MUST declare what modes are supported in `supportsAccountMode` (see below) and if a mode is requested that is not supported by the account, the account MUST revert. +Accounts are NOT REQUIRED to implement all execution modes. The account MUST declare what modes are supported in `supportsExecutionMode` (see below) and if a mode is requested that is not supported by the account, the account MUST revert. The account MUST encode the execution data the following ways: From fe7dce5b1b2e70959997c0bbc30a6dfdd89cdfc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernani=20S=C3=A3o=20Thiago?= Date: Mon, 26 Aug 2024 09:05:36 -0600 Subject: [PATCH 36/79] Update ERC-7432: Update Specification Merged by EIP-Bot. From 18a8146952260cf1dfd399e495da137ccc8aae6d Mon Sep 17 00:00:00 2001 From: Haru <65120405+haruu8@users.noreply.github.com> Date: Tue, 27 Aug 2024 00:56:33 +0000 Subject: [PATCH 37/79] Add ERC: ERC-1155 Multi-Asset extension Merged by EIP-Bot. --- ERCS/erc-7603.md | 159 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 ERCS/erc-7603.md diff --git a/ERCS/erc-7603.md b/ERCS/erc-7603.md new file mode 100644 index 0000000000..1c705bc133 --- /dev/null +++ b/ERCS/erc-7603.md @@ -0,0 +1,159 @@ +--- +eip: 7603 +title: ERC-1155 Multi-Asset extension +description: An interface compatible with ERC-1155 for Multi-Asset tokens with context-dependent asset type output control. +author: Haru (@haruu8) +discussions-to: https://ethereum-magicians.org/t/erc-multi-context-dependent-multi-asset-tokens-eip1155-extension/18303 +status: Draft +type: Standards Track +category: ERC +created: 2024-01-25 +requires: 165, 1155 +--- + +## Abstract + +The Multi-Asset Token standard, compatible with [ERC-1155](./eip-1155.md), facilitates the development of a new fundamental component: the context-dependent data output for each collection. + +The context-dependent data output means that the asset is displayed in an appropriate format based on how the token is accessed. I.e., if the token is being opened in an e-book reader, the PDF asset is displayed; if the token is opened in the marketplace, the PNG or the SVG asset is displayed; if the token is accessed from within a game, the 3D model asset is accessed, and if the token is accessed by an Internet of Things (IoT) hub, the asset providing the necessary addressing and specification information is accessed. + +A Token Collection can have multiple assets (outputs), which can be any file to order them by priority. They do not have to match in mime-type or tokenURI, nor do they depend on one another. Assets are not standalone entities but should be considered “namespaced tokenURIs”. + +## Motivation + +With ERC-1155 compatible tokens being a widespread form of tokens in the Ethereum ecosystem and being used for various use cases, it is time to standardize additional utility for them. Having multiple assets associated with a single Token Collection allows for greater utility, usability, and forward compatibility. This EIP improves upon ERC-1155 in the following areas: + +- [Cross-metaverse compatibility](#cross-metaverse-compatibility) +- [Multi-media output](#multi-media-output) +- [Media redundancy](#media-redundancy) + +### Cross-metaverse compatibility + +The proposal can support any number of different implementations. + +Cross-metaverse compatibility could also be referred to as cross-engine compatibility. An example is where a cosmetic item for game A is unavailable in game B because the frameworks are incompatible. + +Such Tokens can be given further utility through new assets: more games, cosmetic items, and more. + +The following is a more concrete example. One asset is a cosmetic item for game A, a file containing the cosmetic assets. Another is a cosmetic asset file for game B. A third is a generic asset intended to be shown in catalogs, marketplaces, portfolio trackers, or other generalized Token Collection viewers, containing a representation, stylized thumbnail, and animated demo/trailer of the cosmetic item. + +This EIP adds a layer of abstraction, allowing game developers to pull asset data from a user's Tokens directly instead of hard-coding it. + +### Multi-media output + +Tokens of an eBook can be represented as a PDF, MP3, or some other format, depending on what software loads it. If loaded into an eBook reader, a PDF should be displayed, and if loaded into an audiobook application, the MP3 representation should be used. Other metadata could be present in the Tokens (perhaps the book's cover image) for identification on various marketplaces, Search Engine Result Pages (SERPs), or portfolio trackers. + +### Media redundancy + +Many Tokens are minted hastily without best practices in mind. Specifically, many Tokens are minted with metadata centralized on a server somewhere or, in some cases, a hardcoded IPFS gateway which can also go down, instead of just an IPFS hash. + +By adding the same metadata file as different assets, e.g., one asset of metadata and its linked image on Arweave, one asset of this same combination on Sia, another of the same combination on IPFS, etc., the resilience of the metadata and its referenced information increases exponentially as the chances of all the protocols going down at once become less likely. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +```solidity +/// @title ERC-7603 Context-Dependent Multi-Asset Tokens, ERC-1155 Execution +/// @dev See https://eips.ethereum.org/EIPS/erc-7603 + +pragma solidity ^0.8.23; + +interface IERC7603 /* is ERC165 */ { + /** + * @notice Used to notify listeners that an asset object is initialised at `assetId`. + * @param assetId ID of the asset that was initialised + */ + event AssetSet(uint64 assetId); + + /** + * @notice Used to notify listeners that an asset object at `assetId` is added to token's asset + * array. + * @param tokenId An ID of the token that received a new asset + * @param assetId ID of the asset that has been added to the token's assets array + * @param replacesId ID of the asset that would be replaced + */ + event AssetAddedToToken( + uint256[] tokenId, + uint64 indexed assetId, + uint64 indexed replacesId + ); + + /** + * @notice Used to notify listeners that token's priority array is reordered. + * @param tokenId ID of the token that had the asset priority array updated + */ + event AssetPrioritySet(uint256 indexed tokenId); + + /** + * @notice Sets a new priority array for a given token. + * @dev The priority array is a non-sequential list of `uint16`s, where the lowest value is considered highest + * priority. + * @dev Value `0` of a priority is a special case equivalent to uninitialised. + * @dev Requirements: + * + * - `tokenId` must exist. + * - The length of `priorities` must be equal the length of the assets array. + * @dev Emits a {AssetPrioritySet} event. + * @param tokenId ID of the token to set the priorities for + * @param priorities An array of priorities of assets. The succession of items in the priorities array + * matches that of the succession of items in the array + */ + function setPriority(uint256 tokenId, uint64[] calldata priorities) + external; + + /** + * @notice Used to retrieve IDs of assets of given token. + * @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call + * `getAssetMetadata(tokenId, assetId)`. + * @dev You can safely get 10k + * @param tokenId ID of the token to retrieve the IDs of the assets + * @return uint64[] An array of the asset IDs of the given token + */ + function getAssets(uint256 tokenId) + external + view + returns (uint64[] memory); + + /** + * @notice Used to retrieve the priorities of the assets of a given token. + * @dev Asset priorities are a non-sequential array of uint16 values with an array size equal to asset + * priorites. + * @param tokenId ID of the token for which to retrieve the priorities of the assets + * @return uint16[] An array of priorities of the assets of the given token + */ + function getAssetPriorities(uint256 tokenId) + external + view + returns (uint64[] memory); + + /** + * @notice Used to fetch the asset metadata of the specified token's asset with the given index. + * @dev Can be overridden to implement enumerate, fallback or other custom logic. + * @param tokenId ID of the token from which to retrieve the asset metadata + * @param assetId Asset Id, must be in the assets array + * @return string The metadata of the asset belonging to the specified index in the token's assets array + */ + function getAssetMetadata(uint256 tokenId, uint64 assetId) + external + view + returns (string memory); +} + +``` + +## Rationale + +TBD + +## Backwards Compatibility + +The MultiAsset token standard has been made compatible with ERC-1155 in order to take advantage of the robust tooling available for implementations of ERC-1155 and to ensure compatibility with existing ERC-1155 infrastructure. + +## Security Considerations + +Needs discussion. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 37581362e7def0033b3a5280a2ddac69bdb6e580 Mon Sep 17 00:00:00 2001 From: Vectorized Date: Tue, 27 Aug 2024 10:16:43 +0800 Subject: [PATCH 38/79] Add ERC: Minimal Upgradeable Proxies Merged by EIP-Bot. --- ERCS/erc-7760.md | 514 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 514 insertions(+) create mode 100644 ERCS/erc-7760.md diff --git a/ERCS/erc-7760.md b/ERCS/erc-7760.md new file mode 100644 index 0000000000..50fb32b43a --- /dev/null +++ b/ERCS/erc-7760.md @@ -0,0 +1,514 @@ +--- +eip: 7760 +title: Minimal Upgradeable Proxies +description: Minimal upgradeable proxies with immutable arguments and support for onchain implementation queries +author: Atarpara (@Atarpara), JT Riley (@jtriley-eth), Thomas (@0xth0mas), xiaobaiskill (@xiaobaiskill), Vectorized (@Vectorized) +discussions-to: https://ethereum-magicians.org/t/erc-7760-minimal-upgradeable-proxies/20868 +status: Draft +type: Standards Track +category: ERC +created: 2024-08-19 +requires: 1967 +--- + +## Abstract + +This standard defines minimal [ERC-1967](./eip-1967.md) proxies for three patterns: (1) transparent, (2) UUPS, (3) beacon. The proxies support optional immutable arguments which are appended to the end of their runtime bytecode. Additional variants which support onchain implementation querying are provided. + +## Motivation + +Having standardized minimal bytecode for upgradeable proxies enables the following: + +1. Automatic verification on block explorers. +2. Ability for immutable arguments to be queried onchain, as these arguments are stored at the same bytecode offset, +3. Ability for the implementation to be queried and verified onchain. + +The minimal nature of the proxies enables cheaper deployment and runtime costs. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +### General specifications + +All of the following proxies MAY have optional data bytecode appended to the end of their runtime bytecode. + +Emitting the ERC-1967 events during initialization is OPTIONAL. Indexers MUST NOT expect the initialization code to emit the ERC-1967 events. + +### Onchain querying of implementation for I-variants + +The I-variants have logic that returns the implementation baked into their bytecode. + +When called with any 1-byte calldata, these I-variants will return the address (left-zero-padded to 32 bytes) and will not forward the calldata to the target. + +The bytecode of the proxies before any optional immutable arguments MUST be verified with the following steps: + +1. Fetch the bytecode before any immutable arguments with `EXTCODECOPY`. +2. Zeroize any baked-in factory address in the fetched bytecode. +3. Ensure that the hash of the final fetched bytecode matches the expected hash of the bytecode. + +If the hash does not match, the implementation address returned MUST NOT be trusted. + +### Minimal ERC-1967 transparent upgradeable proxy + +The transparent upgradeable proxy is RECOMMENDED to be deployed by a factory that doubles as the account that is authenticated to perform upgrades. An externally owned account may perform the deployment on behalf of the factory. For convention, we will refer to the factory as the immutable account authorized to invoke the upgrade logic on the proxy. + +As the proxy's runtime bytecode contains logic to allow the factory to set any storage slot with any value, the initialization code MAY skip storing the implementation slot. + +The upgrading logic does not emit the ERC-1967 event. Indexers MUST NOT expect the upgrading logic to emit the ERC-1967 events. + +During upgrades, the factory MUST call the upgradeable proxy with following calldata: + +```solidity +abi.encodePacked( + // The new implementation address, converted to a 32-byte word. + uint256(uint160(implementation)), + // ERC-1967 implementation slot. + bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc), + // Optional calldata to be forwarded to the implementation + // via delegatecall after setting the implementation slot. + "" +) +``` + +#### Minimal ERC-1967 transparent upgradeable proxy for (basic variant) + +Runtime bytecode (20-byte factory address subvariant): + +``` +3d3d3373________________________________________14605757363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6052573d6000fd5b3d6000f35b3d356020355560408036111560525736038060403d373d3d355af43d6000803e6052573d6000fd +``` + +where `________________________________________` is the 20-byte factory address. + +Runtime bytecode (14-byte factory address subvariant): + +``` +3d3d336d____________________________14605157363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e604c573d6000fd5b3d6000f35b3d3560203555604080361115604c5736038060403d373d3d355af43d6000803e604c573d6000fd +``` + +where `____________________________` is the 14-byte factory address. + +#### Minimal ERC-1967 transparent upgradeable proxy (I-variant) + +Runtime bytecode (20-byte factory address subvariant): + +``` +3658146083573d3d3373________________________________________14605D57363d3d37363D7f360894a13ba1A3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6058573d6000fd5b3d6000f35b3d35602035556040360380156058578060403d373d3d355af43d6000803e6058573d6000fd5b602060293d393d51543d52593df3 +``` + +where `________________________________________` is the 20-byte factory address. + +Runtime bytecode (14-byte factory address subvariant): + +``` +365814607d573d3d336d____________________________14605757363d3D37363d7F360894A13Ba1A3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6052573d6000fd5b3d6000f35b3d35602035556040360380156052578060403d373d3d355af43d6000803e6052573d6000fd5b602060233d393d51543d52593df3 +``` + +where `____________________________` is the 14-byte factory address. + +### Minimal ERC-1967 UUPS proxy + +As this proxy does not contain upgrading logic, the initialization code MUST store the implementation at the ERC-1967 implementation storage slot `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`. + +#### Minimal ERC-1967 UUPS proxy (basic variant) + +Runtime bytecode: + +``` +363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3 +``` + +#### Minimal ERC-1967 UUPS proxy (I-variant) + +Runtime bytecode: + +``` +365814604357363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3 +``` + +### Minimal ERC-1967 beacon proxy + +As this proxy does not contain upgrading logic, the initialization code MUST store the implementation at the ERC-1967 implementation storage slot `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`. + +#### Minimal ERC-1967 beacon proxy (basic variant) + +Runtime bytecode: + +``` +363d3d373d3d363d602036600436635c60da1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3 +``` + +#### Minimal ERC-1967 beacon proxy (I-variant) + +Runtime bytecode: + +``` +363d3d373d3d363d602036600436635c60da1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3 +``` + +## Rationale + +### No usage of `PUSH0` opcode + +For more widespread EVM compatibility, the proxies deliberately do not use the `PUSH0` opcode proposed in [EIP-3855](./eip-3855.md). + +Converting the proxies to `PUSH0` variants may be done in a separate future ERC. + +### Optimization priorities + +The proxies are first optimized for minimal runtime gas before minimal bytecode size. + +### Minimal nature + +These proxies made from handcrafted EVM bytecode. While utmost efforts have been made to ensure that they are as minimal as possible at the time of development, it is possible that they can be further optimized. If a variant has already been used in the wild, it is preferable to keep their existing layout in this standard, as the benefits of automatic block explorer verification will outweigh the few gas saved during runtime or deployment. + +For historical reference, the [ERC-1167](./eip-1167.md) minimal proxy was not the theoretical minimal at the time of writing. The 0age minimal proxy has lower runtime gas costs and smaller bytecode size. + +### Transparent upgradeable proxy + +The factory address in the transparent upgradeable proxy is baked into the immutable bytecode of the minimal transparent upgradeable proxy. + +This is to save a `SLOAD` for every proxy call. + +As the factory can contain custom authorization logic that allows for admin rotation, we do not lose any flexibility. + +The upgrade logic takes in any 32 byte value and 32 byte storage slot. This is for flexibility and bytecode conciseness. + +We do not lose any security as the implementation can still modify any storage slot. + +### 14-byte factory address subvariants + +It is beneficial to install the transparent upgradeable proxy factory at a vanity address with leading zero bytes so that the proxy's bytecode can be optimized to be shorter. + +A 14-byte factory address (i.e. 6 leading zero bytes) is chosen because it strikes a balance between mining costs and bytecode size. + +### I-variants + +The so-called "I-variants" contain logic that returns the implementation address baked into the proxy bytecode. + +This allows contracts to retrieve the implementation of the proxy onchain in a verifiable way. + +As long as the proxy's runtime bytecode starts with the bytecode in this standard, we can be sure that the implementation address is not spoofed. + +The choice of reserving 1-byte calldata to denote an implementation query request is for efficiency and to prevent calldata collision. Regular ETH transfers use 0-byte calldata, and regular Solidity function calls use calldata that is 4 bytes or longer. + +### Omission of events in bytecode + +This is for minimal bytecode size and deployment costs. + +Most block explorers and indexers are able to deduce the latest implementation without the use of events simply by reading the slots. + +### Immutable arguments are not appended to forwarded calldata + +This is to avoid compatibility and safety issues with other ERC standards that append extra data to the calldata. + +The `EXTCODECOPY` opcode can be used to retrieve the immutable arguments. + +### No fixed initialization code + +As long as the initialization code is able to initialize the relevant ERC-1967 implementation slot where needed (i.e. for the UUPS proxy and Beacon proxy), there is no need for additional requirements on the initialization code. + +### Out of scope topics + +The following topics are intentionally out of scope of this standard, as they can contain custom logic: + +- Factories for proxy deployment. +- Logic for reading and verifying the implementation from the I-variants onchain. +- Beacon for the beacon proxies. + +Nevertheless, they require careful implementation to ensure security and correctness. + +## Backwards Compatibility + +No backward compatibility issues found. + +## Reference Implementation + +### Minimal ERC-1967 transparent upgradeable proxy implementation + +#### Minimal ERC-1967 transparent upgradeable proxy implementation (basic variant) + +```solidity +pragma solidity ^0.8.0; + +library ERC1967MinimalTransparentUpgradeableProxyLib { + function initCodeFor20ByteFactoryAddress() internal view returns (bytes memory) { + return abi.encodePacked( + bytes13(0x607f3d8160093d39f33d3d3373), + address(this), + bytes32(0x14605757363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc), + bytes32(0x3735a920a3ca505d382bbc545af43d6000803e6052573d6000fd5b3d6000f35b), + bytes32(0x3d356020355560408036111560525736038060403d373d3d355af43d6000803e), + bytes7(0x6052573d6000fd) + ); + } + + function initCodeFor14ByteFactoryAddress() internal view returns (bytes memory) { + return abi.encodePacked( + bytes13(0x60793d8160093d39f33d3d336d), + uint112(uint160(address(this))), + bytes32(0x14605157363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc), + bytes32(0x3735a920a3ca505d382bbc545af43d6000803e604c573d6000fd5b3d6000f35b), + bytes32(0x3d3560203555604080361115604c5736038060403d373d3d355af43d6000803e), + bytes7(0x604c573d6000fd) + ); + } + + function initCode() internal view returns (bytes memory) { + if (uint160(address(this)) >> 112 != 0) { + return initCodeFor20ByteFactoryAddress(); + } else { + return initCodeFor14ByteFactoryAddress(); + } + } + + function deploy(address implementation, bytes memory initializationData) + internal + returns (address instance) + { + bytes memory m = initCode(); + assembly { + instance := create(0, add(m, 0x20), mload(m)) + } + require(instance != address(0), "Deployment failed."); + upgrade(instance, implementation, initializationData); + } + + function upgrade(address instance, address implementation, bytes memory upgradeData) internal { + (bool success,) = instance.call( + abi.encodePacked( + // The new implementation address, converted to a 32-byte word. + uint256(uint160(implementation)), + // ERC-1967 implementation slot. + bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc), + // Optional calldata to be forwarded to the implementation + // via delegatecall after setting the implementation slot. + upgradeData + ) + ); + require(success, "Upgrade failed."); + } +} +``` + +#### Minimal ERC-1967 transparent upgradeable proxy implementation (I-variant) + +```solidity +pragma solidity ^0.8.0; + +library ERC1967IMinimalTransparentUpgradeableProxyLib { + function initCodeFor20ByteFactoryAddress() internal view returns (bytes memory) { + return abi.encodePacked( + bytes19(0x60923d8160093d39f33658146083573d3d3373), + address(this), + bytes20(0x14605D57363d3d37363D7f360894a13ba1A32106), + bytes32(0x67c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e60), + bytes32(0x58573d6000fd5b3d6000f35b3d35602035556040360380156058578060403d37), + bytes32(0x3d3d355af43d6000803e6058573d6000fd5b602060293d393d51543d52593df3) + ); + } + + function initCodeFor14ByteFactoryAddress() internal view returns (bytes memory) { + return abi.encodePacked( + bytes19(0x608c3d8160093d39f3365814607d573d3d336d), + uint112(uint160(address(this))), + bytes20(0x14605757363d3D37363d7F360894A13Ba1A32106), + bytes32(0x67c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e60), + bytes32(0x52573d6000fd5b3d6000f35b3d35602035556040360380156052578060403d37), + bytes32(0x3d3d355af43d6000803e6052573d6000fd5b602060233d393d51543d52593df3) + ); + } + + function initCode() internal view returns (bytes memory) { + if (uint160(address(this)) >> 112 != 0) { + return initCodeFor20ByteFactoryAddress(); + } else { + return initCodeFor14ByteFactoryAddress(); + } + } + + function deploy(address implementation, bytes memory initializationData) + internal + returns (address instance) + { + bytes memory m = initCode(); + assembly { + instance := create(0, add(m, 0x20), mload(m)) + } + require(instance != address(0), "Deployment failed."); + upgrade(instance, implementation, initializationData); + } + + function upgrade(address instance, address implementation, bytes memory upgradeData) internal { + (bool success,) = instance.call( + abi.encodePacked( + // The new implementation address, converted to a 32-byte word. + uint256(uint160(implementation)), + // ERC-1967 implementation slot. + bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc), + // Optional calldata to be forwarded to the implementation + // via delegatecall after setting the implementation slot. + upgradeData + ) + ); + require(success, "Upgrade failed."); + } +} +``` + +### Minimal ERC-1967 UUPS proxy implementation + +#### Minimal ERC-1967 UUPS proxy implementation (basic variant) + +```solidity +pragma solidity ^0.8.0; + +library ERC1967MinimalUUPSProxyLib { + function initCode(address implementation, bytes memory args) + internal + pure + returns (bytes memory) + { + uint256 n = 0x003d + args.length; + require(n <= 0xffff, "Immutable args too long."); + return abi.encodePacked( + bytes1(0x61), + uint16(n), + bytes7(0x3d8160233d3973), + implementation, + bytes2(0x6009), + bytes32(0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076), + bytes32(0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3), + args + ); + } + + function deploy(address implementation, bytes memory args) + internal + returns (address instance) + { + bytes memory m = initCode(implementation, args); + assembly { + instance := create(0, add(m, 0x20), mload(m)) + } + require(instance != address(0), "Deployment failed."); + } +} +``` + +#### Minimal ERC-1967 UUPS proxy implementation (I-variant) + +```solidity +pragma solidity ^0.8.0; + +library ERC1967IMinimalUUPSProxyLib { + function initCode(address implementation, bytes memory args) + internal + pure + returns (bytes memory) + { + uint256 n = 0x0052 + args.length; + require(n <= 0xffff, "Immutable args too long."); + return abi.encodePacked( + bytes1(0x61), + uint16(n), + bytes7(0x3d8160233d3973), + implementation, + bytes23(0x600f5155f3365814604357363d3d373d3d363d7f360894), + bytes32(0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4), + bytes32(0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3), + args + ); + } + + function deploy(address implementation, bytes memory args) + internal + returns (address instance) + { + bytes memory m = initCode(implementation, args); + assembly { + instance := create(0, add(m, 0x20), mload(m)) + } + require(instance != address(0), "Deployment failed."); + } +} +``` + +### Minimal ERC-1967 beacon proxy implementation + +#### Minimal ERC-1967 beacon proxy implementation (basic variant) + +```solidity +pragma solidity ^0.8.0; + +library ERC1967MinimalBeaconProxyLib { + function initCode(address beacon, bytes memory args) internal pure returns (bytes memory) { + uint256 n = 0x0052 + args.length; + require(n <= 0xffff, "Immutable args too long."); + return abi.encodePacked( + bytes1(0x61), + uint16(n), + bytes7(0x3d8160233d3973), + beacon, + bytes23(0x60195155f3363d3d373d3d363d602036600436635c60da), + bytes32(0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c), + bytes32(0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3), + args + ); + } + + function deploy(address beacon, bytes memory args) internal returns (address instance) { + bytes memory m = initCode(beacon, args); + assembly { + instance := create(0, add(m, 0x20), mload(m)) + } + require(instance != address(0), "Deployment failed."); + } +} +``` + +#### Minimal ERC-1967 beacon proxy implementation (I-variant) + +```solidity +pragma solidity ^0.8.0; + +library ERC1967IMinimalBeaconProxyLib { + function initCode(address beacon, bytes memory args) internal pure returns (bytes memory) { + uint256 n = 0x0057 + args.length; + require(n <= 0xffff, "Immutable args too long."); + return abi.encodePacked( + bytes1(0x61), + uint16(n), + bytes7(0x3d8160233d3973), + beacon, + bytes28(0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36), + bytes32(0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513), + bytes32(0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3), + args + ); + } + + function deploy(address beacon, bytes memory args) internal returns (address instance) { + bytes memory m = initCode(beacon, args); + assembly { + instance := create(0, add(m, 0x20), mload(m)) + } + require(instance != address(0), "Deployment failed."); + } +} +``` + +## Security Considerations + +### Transparent upgradeable proxy factory security considerations + +To ensure security, the transparent upgradeable proxy factory must implement proper access control to allow proxies to be upgraded by only authorized accounts. + +### Calldata length collision for I-variants + +The I-variants reserve all calldata of length 1 to denote a request to return the implementation. This may pose compatibility issues if the underlying implementation actually uses 1-byte calldata for special purposes. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 5cb2679232df2229caab89ec8384daca77951da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=BBuk?= Date: Tue, 27 Aug 2024 23:00:48 +0200 Subject: [PATCH 39/79] Add ERC: Puppet Proxy Contract Merged by EIP-Bot. --- ERCS/erc-7613.md | 345 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 ERCS/erc-7613.md diff --git a/ERCS/erc-7613.md b/ERCS/erc-7613.md new file mode 100644 index 0000000000..a1f71a8789 --- /dev/null +++ b/ERCS/erc-7613.md @@ -0,0 +1,345 @@ +--- +eip: 7613 +title: Puppet Proxy Contract +description: A proxy that, if called by its deployer, delegates to an implementation specified in calldata. +author: Igor Żuk (@CodeSandwich) +discussions-to: https://ethereum-magicians.org/t/eip-7613-puppet-proxy-contract/18482 +status: Draft +type: Standards Track +category: ERC +created: 2024-02-04 +--- + +## Abstract + +A puppet is a contract that, when called, acts like an empty account. It doesn't do anything and it has no API, except when it is called by the address that deployed it. In that case, it delegates the call to the address passed to it in calldata. This gives the deployer the ability to execute any logic they want in the context of the puppet. + +## Motivation + +A puppet can be used as an alternative account of its deployer. It has a different address, so it has a separate set of asset balances. This enables sophisticated accounting, e.g. each user of a protocol can get their own address where assets can be sent and stored. The user may call the protocol contract, which in turn will deploy a new puppet and consider it assigned to the user. If the puppet is deployed under a predictable address, e.g. by using the user's address as the CREATE2 salt, the puppet may not even need to be deployed before funds are sent to its address. From now on the protocol will consider all the assets sent to the puppet as owned by the user. If the protocol needs to move the funds out from the puppet address, it can call the puppet ordering it to delegate to a function transferring the assets to arbitrary addresses, or making arbitrary calls triggering approved transfers to other contracts. + +Puppets can be used as an alternative to approved transfers when loading funds into the protocol. Any contract and any wallet can transfer the funds to the puppet address assigned to the user without making any approvals or calling the protocol contracts. Funds can be loaded across multiple transactions and potentially from multiple sources. To funnel funds from another protocol, there's no need for integration in the 3rd party contracts as long as they are capable of transferring funds to an arbitrary address. Wallets limited to plain [ERC-20](./eip-20.md) transfers and stripped of any web3 functionality can be used to load funds into the protocol. The users of the fully featured wallets don't need to sign opaque calldata blobs that may be harmful or approve the protocol to take their tokens, they only need to make a transfer, which is a simple process with a familiar UX. When the funds are already stored in the puppet assigned to the user, somebody needs to call the protocol so it's notified that the funds were loaded. Depending on the protocol and its API this call may or may not be permissionless potentially making the UX even more convenient with gasless transactions or 3rd parties covering the gas cost. Some protocols don't need the users to specify what needs to be done with the loaded funds or they allow the users to configure that in advance. Most of the protocols using approved transfers to load funds may benefit from using the puppets. + +The puppet's logic doesn't need to be ever upgraded. To change its behavior the deployer needs to change the address it passes to the puppet to delegate to or the calldata it passes for delegation. The entire fleet of puppets deployed by a single contract can be upgraded by upgrading the contract that deployed them, without using beacons. A nice trick is that the deployer can make the puppet delegate to the address holding the deployer's own logic, so the puppet's logic is encapsulated in the deployer's. + +A puppet is unable to expose any API to any caller except the deployer. If a 3rd party needs to be able to somehow make the puppet execute some logic, it can't be requested by directly calling the puppet. Instead, the deployer needs to expose a function that if called by the 3rd parties, will call the puppet, and make it execute the desired logic. Mechanisms expecting contracts to expose some APIs don't work with puppet, e.g. [ERC-721](./eip-721.md)'s `safeTransfer`s. + +This standard defines the puppet as a blob of bytes used as creation code, which enables integration with many frameworks and codebases written in variety of languages. The specific tooling is outside of the scope of this standard, but it should be easy to create the libraries and helpers necessary for usage in practice. All the implementations will be interoperable because they will be creating identical puppets and if CREATE2 is used, they will have deterministic addresses predictable by all implementations. + +Because the puppet can be deployed under a predictable address despite having no fixed logic, in some cases it can be used as a CREATE3 alternative. It can be also used as a full replacement of the CREATE3 factory by using a puppet deployed using CREATE2 to deploy arbitrary code using plain CREATE. + +Deploying a new puppet is almost as cheap as deploying a new clone proxy. Its whole deployed bytecode is 66 bytes, and its creation code is 62 bytes. Just like clone proxy, it can be deployed using just the Solidity scratch space in memory. The cost to deploy a puppet is 45K gas, only 4K more than a clone. Because the bytecode is not compiled, it can be reliably deployed under a predictable CREATE2 address regardless of the compiler version. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +To delegate, the deployer must prepend the calldata with an ABI-encoded address to delegate to. +All the data after the address will be passed verbatim as the delegation calldata. +If the caller isn't the deployer, the calldata is shorter than 32 bytes, or it doesn't start with +an address left-padded with zeros, the puppet doesn't do anything. +This lets the deployer make a plain native tokens transfer to the puppet, +it will have an empty calldata, and the puppet will accept the transfer without delegating. + +The puppet is deployed with this creation code: +``` +0x604260126D60203D3D3683113D3560A01C17733D3360147F331817604057823603803D943D373D3D355AF43D82803E903D91604057FD5BF36034525252F3 +``` + +The bytecode breakdown: +``` +// The creation code. +// [code 1] and [code 2] are parts of the deployed code, +// placed respectively before and after the deployer's address. +// | Opcode used | Hex value | Stack content after executing +// Code size and offset in memory +// | PUSH1 | 60 42 | 66 +// | PUSH1 | 60 12 | 18 66 +// The code before the deployer's address and where it's stored in memory +// | PUSH14 | 6D [code 1] | [code 1] 18 66 +// | RETURNDATASIZE | 3D | 0 [code 1] 18 66 +// The deployer's address and where it's stored in memory +// | CALLER | 33 | [deployer] 0 [code 1] 18 66 +// | PUSH1 | 60 14 | 20 [deployer] 0 [code 1] 18 66 +// The code after the deployer's address and where it's stored in memory +// | PUSH32 | 7F [code 2] | [code 2] 20 [deployer] 0 [code 1] 18 66 +// | PUSH1 | 60 34 | 52 [code 2] 20 [deployer] 0 [code 1] 18 66 +// Return the entire code +// | MSTORE | 52 | 20 [deployer] 0 [code 1] 18 66 +// | MSTORE | 52 | 0 [code 1] 18 66 +// | MSTORE | 52 | 18 66 +// | RETURN | F3 | + +// The deployed code. +// `deployer` is the deployer's address. +// | Opcode used | Hex value | Stack content after executing +// Push some constants +// | PUSH1 | 60 20 | 32 +// | RETURNDATASIZE | 3D | 0 32 +// | RETURNDATASIZE | 3D | 0 0 32 +// Do not delegate if calldata shorter than 32 bytes +// | CALLDATASIZE | 36 | [calldata size] 0 0 32 +// | DUP4 | 83 | 32 [calldata size] 0 0 32 +// | GT | 11 | [do not delegate] 0 0 32 +// Do not delegate if the first word of calldata is not a zero-padded address +// | RETURNDATASIZE | 3D | 0 [do not delegate] 0 0 32 +// | CALLDATALOAD | 35 | [first word] [do not delegate] 0 0 32 +// | PUSH1 | 60 A0 | 160 [first word] [do not delegate] 0 0 32 +// | SHR | 1C | [first word upper bits] [do not delegate] 0 0 32 +// | OR | 17 | [do not delegate] 0 0 32 +// Do not delegate if not called by the deployer +// | PUSH20 | 73 [deployer] | [deployer] [do not delegate] 0 0 32 +// | CALLER | 33 | [sender] [deployer] [do not delegate] 0 0 32 +// | XOR | 18 | [sender not deployer] [do not delegate] 0 0 32 +// | OR | 17 | [do not delegate] 0 0 32 +// Skip to the return if should not delegate +// | PUSH1 | 60 40 | [success branch] [do not delegate] 0 0 32 +// | JUMPI | 57 | 0 0 32 +// Calculate the payload size +// | DUP3 | 82 | 32 0 0 32 +// | CALLDATASIZE | 36 | [calldata size] 32 0 0 32 +// | SUB | 03 | [payload size] 0 0 32 +// Copy the payload from calldata +// | DUP1 | 80 | [payload size] [payload size] 0 0 32 +// | RETURNDATASIZE | 3D | 0 [payload size] [payload size] 0 0 32 +// | SWAP5 | 94 | 32 [payload size] [payload size] 0 0 0 +// | RETURNDATASIZE | 3D | 0 32 [payload size] [payload size] 0 0 0 +// | CALLDATACOPY | 37 | [payload size] 0 0 0 +// Delegate call +// | RETURNDATASIZE | 3D | 0 [payload size] 0 0 0 +// | RETURNDATASIZE | 3D | 0 0 [payload size] 0 0 0 +// | CALLDATALOAD | 35 | [delegate to] 0 [payload size] 0 0 0 +// | GAS | 5A | [gas] [delegate to] 0 [payload size] 0 0 0 +// | DELEGATECALL | F4 | [success] 0 +// Copy return data +// | RETURNDATASIZE | 3D | [return size] [success] 0 +// | DUP3 | 82 | 0 [return size] [success] 0 +// | DUP1 | 80 | 0 0 [return size] [success] 0 +// | RETURNDATACOPY | 3E | [success] 0 +// Return +// | SWAP1 | 90 | 0 [success] +// | RETURNDATASIZE | 3D | [return size] 0 [success] +// | SWAP2 | 91 | [success] 0 [return size] +// | PUSH1 | 60 40 | [success branch] [success] 0 [return size] +// | JUMPI | 57 | 0 [return size] +// | REVERT | FD | +// | JUMPDEST | 5B | 0 [return size] +// | RETURN | F3 | +``` + +## Rationale + +The main goals of the puppet design are low cost and modularity. It should be cheap to deploy and cheap to interact with. The contract should be self-contained, simple to reason about, and easy to use as an architectural building block. + +The puppet behavior could be implemented fairly easily in Solidity with some inline Yul for delegation. This would make the bytecode much larger and more expensive to deploy. It would also be different depending on the compiler version and configuration, so deployments under predictable addresses using CREATE2 would be trickier. + +A workaround for the problems with the above solution could be to use the clone proxy pattern to deploy copies of the puppet implementation. It would make the cost to deploy each puppet a little lower than deploying the bytecode proposed in this document, and the addresses of the clones would be predictable when deploying using CREATE2. The downside is that now there would be 1 extra delegation for each call, from the clone proxy to the puppet implementation address, which costs gas. The architecture of such solution is also more complicated with more contracts involved, and it requires the initialization step of deploying the puppet implementation before any clone can be deployed. The initialization step limits the CREATE2 address predictability because the creation code of the clone proxy includes the implementation address, which affects the deployment address. + +Another alternative is to use the beacon proxy pattern. Making a Solidity API call safely is a relatively complex procedure that takes up a non-trivial space in the bytecode. To lower the cost of the puppets, the beacon proxy probably should be used with the clone proxy, which would be even more complicated and more expensive to use than the above solutions. Querying a beacon for the delegation address is less flexible than passing it in calldata, it requires updating the state of the beacon to change the address. + +## Backwards Compatibility + +No backward compatibility issues found. + +The puppet bytecode doesn't use PUSH0, because many chains don't support it yet. + +## Test Cases + +Here are the tests verifying that the bytecode and the reference implementation library are working as expected, using the Foundry test tools: + +```solidity +pragma solidity ^0.8.0; + +import {Test} from "forge-std/Test.sol"; +import {Puppet} from "src/Puppet.sol"; + +contract Logic { + string public constant ERROR = "Failure called"; + + fallback(bytes calldata data) external returns (bytes memory) { + return abi.encode(data); + } + + function success(uint256 arg) external payable returns (address, uint256, uint256) { + return (address(this), arg, msg.value); + } + + function failure() external pure { + revert(ERROR); + } +} + +contract PuppetTest is Test { + address puppet = Puppet.deploy(); + address logic = address(new Logic()); + + function logicFailurePayload() internal view returns (bytes memory) { + return Puppet.delegationCalldata(logic, abi.encodeWithSelector(Logic.failure.selector)); + } + + function call(address target, bytes memory data) internal returns (bytes memory) { + return call(target, data, 0); + } + + function call(address target, bytes memory data, uint256 value) + internal + returns (bytes memory) + { + (bool success, bytes memory returned) = target.call{value: value}(data); + require(success, "Unexpected revert"); + return returned; + } + + function testDeployDeterministic() public { + bytes32 salt = keccak256("Puppet"); + address newPuppet = Puppet.deployDeterministic(salt); + assertEq( + newPuppet, Puppet.predictDeterministicAddress(salt, address(this)), "Invalid address" + ); + assertEq( + newPuppet, Puppet.predictDeterministicAddress(salt), "Invalid address when no deployer" + ); + assertEq(newPuppet.code, puppet.code, "Invalid code"); + } + + function testPuppetDelegates() public { + uint256 arg = 1234; + bytes memory data = abi.encodeWithSelector(Logic.success.selector, arg); + bytes memory payload = Puppet.delegationCalldata(logic, data); + uint256 value = 5678; + + bytes memory returned = call(puppet, payload, value); + + (address thisAddr, uint256 receivedArg, uint256 receivedValue) = + abi.decode(returned, (address, uint256, uint256)); + assertEq(thisAddr, puppet, "Invalid delegation context"); + assertEq(receivedArg, arg, "Invalid argument"); + assertEq(receivedValue, value, "Invalid value"); + } + + function testPuppetDelegatesWithEmptyCalldata() public { + bytes memory payload = Puppet.delegationCalldata(logic, ""); + bytes memory returned = call(puppet, payload); + bytes memory data = abi.decode(returned, (bytes)); + assertEq(data.length, 0, "Delegated with non-empty calldata"); + } + + function testPuppetBubblesRevertPayload() public { + vm.expectRevert(bytes(Logic(logic).ERROR())); + call(puppet, logicFailurePayload()); + } + + function testPuppetDoesNothingForNonDeployer() public { + vm.prank(address(1234)); + call(puppet, logicFailurePayload()); + } + + function testCallingWithCalldataShorterThan32BytesDoesNothing() public { + address delegateTo = address(uint160(1234) << 8); + bytes memory payload = abi.encodePacked(bytes31(bytes32(uint256(uint160(delegateTo))))); + vm.mockCallRevert(delegateTo, "", "Logic called"); + call(puppet, payload); + } + + function testCallingWithDelegationAddressOver20BytesDoesNothing() public { + bytes memory payload = logicFailurePayload(); + payload[11] = 0x01; + call(puppet, payload); + } + + function testCallingPuppetDoesNothing() public { + // Forge the calldata, so if puppet uses it to delegate, it will run `Logic.failure` + uint256 forged = uint256(uint160(address(this))) << 32; + forged |= uint32(Logic.failure.selector); + bytes memory payload = abi.encodeWithSignature("abc(uint)", forged); + call(puppet, payload); + } + + function testTransferFromDeployerToPuppet() public { + uint256 amt = 123; + payable(puppet).transfer(amt); + assertEq(puppet.balance, amt, "Invalid balance"); + } + + function testTransferToPuppet() public { + uint256 amt = 123; + address sender = address(456); + payable(sender).transfer(amt); + vm.prank(sender); + payable(puppet).transfer(amt); + assertEq(puppet.balance, amt, "Invalid balance"); + } +} +``` + +## Reference Implementation + +The puppet bytecode is explained in the specification section. Here's the example helper library: + +```solidity +library Puppet { + bytes internal constant CREATION_CODE = + hex"604260126D60203D3D3683113D3560A01C17733D3360147F33181760405782" + hex"3603803D943D373D3D355AF43D82803E903D91604057FD5BF36034525252F3"; + bytes32 internal constant CREATION_CODE_HASH = keccak256(CREATION_CODE); + + /// @notice Deploy a new puppet. + /// @return instance The address of the puppet. + function deploy() internal returns (address instance) { + bytes memory creationCode = CREATION_CODE; + assembly { + instance := create(0, add(creationCode, 32), mload(creationCode)) + } + require(instance != address(0), "Failed to deploy the puppet"); + } + + /// @notice Deploy a new puppet under a deterministic address. + /// @param salt The salt to use for the deterministic deployment. + /// @return instance The address of the puppet. + function deployDeterministic(bytes32 salt) internal returns (address instance) { + bytes memory creationCode = CREATION_CODE; + assembly { + instance := create2(0, add(creationCode, 32), mload(creationCode), salt) + } + require(instance != address(0), "Failed to deploy the puppet"); + } + + /// @notice Calculate the deterministic address for a puppet deployment made by this contract. + /// @param salt The salt to use for the deterministic deployment. + /// @return predicted The address of the puppet. + function predictDeterministicAddress(bytes32 salt) internal view returns (address predicted) { + return predictDeterministicAddress(salt, address(this)); + } + + /// @notice Calculate the deterministic address for a puppet deployment. + /// @param salt The salt to use for the deterministic deployment. + /// @param deployer The address of the deployer of the puppet. + /// @return predicted The address of the puppet. + function predictDeterministicAddress(bytes32 salt, address deployer) + internal + pure + returns (address predicted) + { + bytes32 hash = keccak256(abi.encodePacked(hex"ff", deployer, salt, CREATION_CODE_HASH)); + return address(uint160(uint256(hash))); + } + + function delegationCalldata(address delegateTo, bytes memory data) + internal + pure + returns (bytes memory payload) + { + return abi.encodePacked(bytes32(uint256(uint160(delegateTo))), data); + } +} +``` + +## Security Considerations + +The bytecode is made to resemble clone proxy's wherever it makes sense to simplify auditing. + +ABI-encoding the delegation address protects the deployer from being tricked by a 3rd party into calling the puppet and making it delegate to an arbitrary address. Such scenario would only be possible if the deployer called on the puppet a function with the selector `0x00000000`, which as of now doesn't come from any reasonably named function. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 22ace52a8260af46218e4412321de1d3cfa6da5d Mon Sep 17 00:00:00 2001 From: Dongri Jin Date: Wed, 28 Aug 2024 06:18:34 +0900 Subject: [PATCH 40/79] Add ERC: Transfer With Authorization Merged by EIP-Bot. --- ERCS/erc-7758.md | 530 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 530 insertions(+) create mode 100644 ERCS/erc-7758.md diff --git a/ERCS/erc-7758.md b/ERCS/erc-7758.md new file mode 100644 index 0000000000..1219feda4b --- /dev/null +++ b/ERCS/erc-7758.md @@ -0,0 +1,530 @@ +--- +eip: 7758 +title: Transfer With Authorization +description: Transfer fungible assets via a signed authorization. +author: Peter Jihoon Kim (@petejkim), Kevin Britz (@kbrizzle), David Knott (@DavidLKnott), Dongri Jin (@dongri) +discussions-to: https://ethereum-magicians.org/t/erc-7758-transfer-with-authorization/20859 +status: Draft +type: Standards Track +category: ERC +created: 2020-09-28 +requires: 20, 712 +--- + +## Abstract + +A set of functions to enable meta-transactions and atomic interactions with [ERC-20](./eip-20.md) token contracts via signatures conforming to the [EIP-712](./eip-712.md) typed message signing specification. + +This enables the user to: + +- delegate the gas payment to someone else, +- pay for gas in the token itself rather than in ETH, +- perform one or more token transfers and other operations in a single atomic transaction, +- transfer ERC-20 tokens to another address, and have the recipient submit the transaction, +- batch multiple transactions with minimal overhead, and +- create and perform multiple transactions without having to worry about them failing due to accidental nonce-reuse or improper ordering by the miner. + +## Motivation + +There is an existing spec, [EIP-2612](./eip-2612), that also allows meta-transactions, and it is encouraged that a contract implements both for maximum compatibility. The two primary differences between this spec and EIP-2612 are that: + +- EIP-2612 uses sequential nonces, but this uses random 32-byte nonces, and that +- EIP-2612 relies on the ERC-20 `approve`/`transferFrom` ("ERC-20 allowance") pattern. + +The biggest issue with the use of sequential nonces is that it does not allow users to perform more than one transaction at time without risking their transactions failing, because: + +- DApps may unintentionally reuse nonces that have not yet been processed in the blockchain. +- Miners may process the transactions in the incorrect order. + +This can be especially problematic if the gas prices are very high and transactions often get queued up and remain unconfirmed for a long time. Non-sequential nonces allow users to create as many transactions as they want at the same time. + +The ERC-20 allowance mechanism is susceptible to the multiple withdrawal attack, and encourages antipatterns such as the use of the "infinite" allowance. The wide-prevalence of upgradeable contracts have made the conditions favorable for these attacks to happen in the wild. + +The deficiencies of the ERC-20 allowance pattern brought about the development of alternative token standards such as the [ERC-777](./eip-777). However, they haven't been able to gain much adoption due to compatibility and potential security issues. + +## Specification + +### Event + +```solidity +event AuthorizationUsed( + address indexed authorizer, + bytes32 indexed nonce +); + +// keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)") +bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267; + +// keccak256("ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)") +bytes32 public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH = 0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8; + +/** + * @notice Returns the state of an authorization + * @dev Nonces are randomly generated 32-byte data unique to the authorizer's + * address + * @param authorizer Authorizer's address + * @param nonce Nonce of the authorization + * @return True if the nonce is used + */ +function authorizationState( + address authorizer, + bytes32 nonce +) external view returns (bool); + +/** + * @notice Execute a transfer with a signed authorization + * @param from Payer's address (Authorizer) + * @param to Payee's address + * @param value Amount to be transferred + * @param validAfter The time after which this is valid (unix time) + * @param validBefore The time before which this is valid (unix time) + * @param nonce Unique nonce + * @param v v of the signature + * @param r r of the signature + * @param s s of the signature + */ +function transferWithAuthorization( + address from, + address to, + uint256 value, + uint256 validAfter, + uint256 validBefore, + bytes32 nonce, + uint8 v, + bytes32 r, + bytes32 s +) external; + +/** + * @notice Receive a transfer with a signed authorization from the payer + * @dev This has an additional check to ensure that the payee's address matches + * the caller of this function to prevent front-running attacks. (See security + * considerations) + * @param from Payer's address (Authorizer) + * @param to Payee's address + * @param value Amount to be transferred + * @param validAfter The time after which this is valid (unix time) + * @param validBefore The time before which this is valid (unix time) + * @param nonce Unique nonce + * @param v v of the signature + * @param r r of the signature + * @param s s of the signature + */ +function receiveWithAuthorization( + address from, + address to, + uint256 value, + uint256 validAfter, + uint256 validBefore, + bytes32 nonce, + uint8 v, + bytes32 r, + bytes32 s +) external; +``` + +**Optional:** + +``` +event AuthorizationCanceled( + address indexed authorizer, + bytes32 indexed nonce +); + +// keccak256("CancelAuthorization(address authorizer,bytes32 nonce)") +bytes32 public constant CANCEL_AUTHORIZATION_TYPEHASH = 0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429; + +/** + * @notice Attempt to cancel an authorization + * @param authorizer Authorizer's address + * @param nonce Nonce of the authorization + * @param v v of the signature + * @param r r of the signature + * @param s s of the signature + */ +function cancelAuthorization( + address authorizer, + bytes32 nonce, + uint8 v, + bytes32 r, + bytes32 s +) external; +``` + + +The arguments `v`, `r`, and `s` must be obtained using the [EIP-712](./eip-712.md) typed message signing spec. + +**Example:** + +``` +DomainSeparator := Keccak256(ABIEncode( + Keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ), + Keccak256("USD Coin"), // name + Keccak256("2"), // version + 1, // chainId + 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 // verifyingContract +)) +``` + +With the domain separator, the typehash, which is used to identify the type of the EIP-712 message being used, and the values of the parameters, you are able to derive a Keccak-256 hash digest which can then be signed using the token holder's private key. + +**Example:** + +``` +// Transfer With Authorization +TypeHash := Keccak256( + "TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)" +) +Params := { From, To, Value, ValidAfter, ValidBefore, Nonce } + +// ReceiveWithAuthorization +TypeHash := Keccak256( + "ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)" +) +Params := { From, To, Value, ValidAfter, ValidBefore, Nonce } + +// CancelAuthorization +TypeHash := Keccak256( + "CancelAuthorization(address authorizer,bytes32 nonce)" +) +Params := { Authorizer, Nonce } +``` + +``` +// "‖" denotes concatenation. +Digest := Keecak256( + 0x1901 ‖ DomainSeparator ‖ Keccak256(ABIEncode(TypeHash, Params...)) +) + +{ v, r, s } := Sign(Digest, PrivateKey) +``` + +Smart contract functions that wrap `receiveWithAuthorization` call may choose to reduce the number of arguments by accepting the full ABI-encoded set of arguments for the `receiveWithAuthorization` call as a single argument of the type `bytes`. + +**Example:** + +```solidity +// keccak256("receiveWithAuthorization(address,address,uint256,uint256,uint256,bytes32,uint8,bytes32,bytes32)")[0:4] +bytes4 private constant _RECEIVE_WITH_AUTHORIZATION_SELECTOR = 0xef55bec6; + +function deposit(address token, bytes calldata receiveAuthorization) + external + nonReentrant +{ + (address from, address to, uint256 amount) = abi.decode( + receiveAuthorization[0:96], + (address, address, uint256) + ); + require(to == address(this), "Recipient is not this contract"); + + (bool success, ) = token.call( + abi.encodePacked( + _RECEIVE_WITH_AUTHORIZATION_SELECTOR, + receiveAuthorization + ) + ); + require(success, "Failed to transfer tokens"); + + ... +} +``` + +### Use with web3 providers + +The signature for an authorization can be obtained using a web3 provider with the `eth_signTypedData{_v4}` method. + +**Example:** + +```javascript +const data = { + types: { + EIP712Domain: [ + { name: "name", type: "string" }, + { name: "version", type: "string" }, + { name: "chainId", type: "uint256" }, + { name: "verifyingContract", type: "address" }, + ], + TransferWithAuthorization: [ + { name: "from", type: "address" }, + { name: "to", type: "address" }, + { name: "value", type: "uint256" }, + { name: "validAfter", type: "uint256" }, + { name: "validBefore", type: "uint256" }, + { name: "nonce", type: "bytes32" }, + ], + }, + domain: { + name: tokenName, + version: tokenVersion, + chainId: selectedChainId, + verifyingContract: tokenAddress, + }, + primaryType: "TransferWithAuthorization", + message: { + from: userAddress, + to: recipientAddress, + value: amountBN.toString(10), + validAfter: 0, + validBefore: Math.floor(Date.now() / 1000) + 3600, // Valid for an hour + nonce: Web3.utils.randomHex(32), + }, +}; + +const signature = await ethereum.request({ + method: "eth_signTypedData_v4", + params: [userAddress, JSON.stringify(data)], +}); + +const v = "0x" + signature.slice(130, 132); +const r = signature.slice(0, 66); +const s = "0x" + signature.slice(66, 130); +``` + +## Rationale + +### Unique Random Nonce, Instead of Sequential Nonce + +One might say transaction ordering is one reason why sequential nonces are preferred. However, sequential nonces do not actually help achieve transaction ordering for meta transactions in practice: + +- For native Ethereum transactions, when a transaction with a nonce value that is too-high is submitted to the network, it will stay pending until the transactions consuming the lower unused nonces are confirmed. +- However, for meta-transactions, when a transaction containing a sequential nonce value that is too high is submitted, instead of staying pending, it will revert and fail immediately, resulting in wasted gas. +- The fact that miners can also reorder transactions and include them in the block in the order they want (assuming each transaction was submitted to the network by different meta-transaction relayers) also makes it possible for the meta-transactions to fail even if the nonces used were correct. (e.g. User submits nonces 3, 4 and 5, but miner ends up including them in the block as 4,5,3, resulting in only 3 succeeding) +- Lastly, when using different applications simultaneously, in absence of some sort of an off-chain nonce-tracker, it is not possible to determine what the correct next nonce value is if there exists nonces that are used but haven't been submitted and confirmed by the network. +- Under high gas price conditions, transactions can often "get stuck" in the pool for a long time. Under such a situation, it is much more likely for the same nonce to be unintentionally reused twice. For example, if you make a meta-transaction that uses a sequential nonce from one app, and switch to another app to make another meta-transaction before the previous one confirms, the same nonce will be used if the app relies purely on the data available on-chain, resulting in one of the transactions failing. +- In conclusion, the only way to guarantee transaction ordering is for relayers to submit transactions one at a time, waiting for confirmation between each submission (and the order in which they should be submitted can be part of some off-chain metadata), rendering sequential nonce irrelevant. + +### Valid After and Valid Before + +- Relying on relayers to submit transactions for you means you may not have exact control over the timing of transaction submission. +- These parameters allow the user to schedule a transaction to be only valid in the future or before a specific deadline, protecting the user from potential undesirable effects that may be caused by the submission being made either too late or too early. + +### EIP-712 + +- EIP-712 ensures that the signatures generated are valid only for this specific instance of the token contract and cannot be replayed on a different network with a different chain ID. +- This is achieved by incorporating the contract address and the chain ID in a Keccak-256 hash digest called the domain separator. The actual set of parameters used to derive the domain separator is up to the implementing contract, but it is highly recommended that the fields `verifyingContract` and `chainId` are included. + +## Backwards Compatibility + +New contracts benefit from being able to directly utilize this proposal in order to create atomic transactions, but existing contracts may still rely on the conventional [ERC-20](./eip-20.md) allowance pattern (`approve`/`transferFrom`). + +In order to add support for this proposal to existing contracts ("parent contract") that use the ERC-20 allowance pattern, a forwarding contract ("forwarder") can be constructed that takes an authorization and does the following: + +1. Extract the user and deposit amount from the authorization +2. Call `receiveWithAuthorization` to transfer specified funds from the user to the forwarder +3. Approve the parent contract to spend funds from the forwarder +4. Call the method on the parent contract that spends the allowance set from the forwarder +5. Transfer the ownership of any resulting tokens back to the user + +**Example:** + +```solidity +interface IDeFiToken { + function deposit(uint256 amount) external returns (uint256); + + function transfer(address account, uint256 amount) + external + returns (bool); +} + +contract DepositForwarder { + bytes4 private constant _RECEIVE_WITH_AUTHORIZATION_SELECTOR = 0xef55bec6; + + IDeFiToken private _parent; + IERC20 private _token; + + constructor(IDeFiToken parent, IERC20 token) public { + _parent = parent; + _token = token; + } + + function deposit(bytes calldata receiveAuthorization) + external + nonReentrant + returns (uint256) + { + (address from, address to, uint256 amount) = abi.decode( + receiveAuthorization[0:96], + (address, address, uint256) + ); + require(to == address(this), "Recipient is not this contract"); + + (bool success, ) = address(_token).call( + abi.encodePacked( + _RECEIVE_WITH_AUTHORIZATION_SELECTOR, + receiveAuthorization + ) + ); + require(success, "Failed to transfer to the forwarder"); + + require( + _token.approve(address(_parent), amount), + "Failed to set the allowance" + ); + + uint256 tokensMinted = _parent.deposit(amount); + require( + _parent.transfer(from, tokensMinted), + "Failed to transfer the minted tokens" + ); + + uint256 remainder = _token.balanceOf(address(this); + if (remainder > 0) { + require( + _token.transfer(from, remainder), + "Failed to refund the remainder" + ); + } + + return tokensMinted; + } +} +``` + +## Reference Implementation + +### `EIP7758.sol` + +```solidity +abstract contract EIP7758 is IERC20Transfer, EIP712Domain { + // keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)") + bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267; + + // keccak256("ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)") + bytes32 public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH = 0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8; + + mapping(address => mapping(bytes32 => bool)) internal _authorizationStates; + + event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce); + + string internal constant _INVALID_SIGNATURE_ERROR = "EIP7758: invalid signature"; + + function authorizationState(address authorizer, bytes32 nonce) + external + view + returns (bool) + { + return _authorizationStates[authorizer][nonce]; + } + + function transferWithAuthorization( + address from, + address to, + uint256 value, + uint256 validAfter, + uint256 validBefore, + bytes32 nonce, + uint8 v, + bytes32 r, + bytes32 s + ) external { + require(now > validAfter, "EIP7758: authorization is not yet valid"); + require(now < validBefore, "EIP7758: authorization is expired"); + require( + !_authorizationStates[from][nonce], + "EIP7758: authorization is used" + ); + + bytes memory data = abi.encode( + TRANSFER_WITH_AUTHORIZATION_TYPEHASH, + from, + to, + value, + validAfter, + validBefore, + nonce + ); + require( + EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == from, + "EIP7758: invalid signature" + ); + + _authorizationStates[from][nonce] = true; + emit AuthorizationUsed(from, nonce); + + _transfer(from, to, value); + } +} +``` + +### `IERC20Transfer.sol` + +```solidity +abstract contract IERC20Transfer { + function _transfer( + address sender, + address recipient, + uint256 amount + ) internal virtual; +} +``` + +### `EIP712Domain.sol` +```solidity +abstract contract EIP712Domain { + bytes32 public DOMAIN_SEPARATOR; +} +``` + +### `EIP712.sol` + +```solidity +library EIP712 { + // keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)") + bytes32 public constant EIP712_DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; + + function makeDomainSeparator(string memory name, string memory version) + internal + view + returns (bytes32) + { + uint256 chainId; + assembly { + chainId := chainid() + } + + return + keccak256( + abi.encode( + EIP712_DOMAIN_TYPEHASH, + keccak256(bytes(name)), + keccak256(bytes(version)), + bytes32(chainId), + address(this) + ) + ); + } + + function recover( + bytes32 domainSeparator, + uint8 v, + bytes32 r, + bytes32 s, + bytes memory typeHashAndData + ) internal pure returns (address) { + bytes32 digest = keccak256( + abi.encodePacked( + "\x19\x01", + domainSeparator, + keccak256(typeHashAndData) + ) + ); + address recovered = ecrecover(digest, v, r, s); + require(recovered != address(0), "EIP712: invalid signature"); + return recovered; + } +} +``` + +## Security Considerations + +Use `receiveWithAuthorization` instead of `transferWithAuthorization` when calling from other smart contracts. It is possible for an attacker watching the transaction pool to extract the transfer authorization and front-run the `transferWithAuthorization` call to execute the transfer without invoking the wrapper function. This could potentially result in unprocessed, locked up deposits. `receiveWithAuthorization` prevents this by performing an additional check that ensures that the caller is the payee. Additionally, if there are multiple contract functions accepting receive authorizations, the app developer could dedicate some leading bytes of the nonce could as the identifier to prevent cross-use. + +When submitting multiple transfers simultaneously, be mindful of the fact that relayers and miners will decide the order in which they are processed. This is generally not a problem if the transactions are not dependent on each other, but for transactions that are highly dependent on each other, it is recommended that the signed authorizations are submitted one at a time. + +The zero address must be rejected when using `ecrecover` to prevent unauthorized transfers and approvals of funds from the zero address. The built-in `ecrecover` returns the zero address when a malformed signature is provided. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 4c9859f541f5eea0ba865c1b4c5066ac7520aa1a Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:42:47 -0400 Subject: [PATCH 41/79] Update ERC-3770: Fix broken links and formatting (#531) * Update ERC-3770: Fix broken links and formatting * use relative links only, for website --- ERCS/erc-3770.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ERCS/erc-3770.md b/ERCS/erc-3770.md index fbed54b7c5..7b3a48ad43 100644 --- a/ERCS/erc-3770.md +++ b/ERCS/erc-3770.md @@ -12,8 +12,8 @@ created: 2021-08-26 ## Abstract -[ERC-3770](./eip-3770.md) introduces a new address standard to be adapted by wallets and dApps to display chain-specific addresses by using a human-reacable prefix. - +[ERC-3770](./eip-3770.md) introduces a new address standard to be adapted by wallets and dApps to display chain-specific addresses by using a human-readable prefix. + ## Motivation The need for this proposal emerges from the increasing adoption of non-Ethereum Mainnet chains that use the Ethereum Virtual Machine (EVM). In this context, addresses become ambiguous, as the same address may refer to an EOA on chain X or a smart contract on chain Y. This will eventually lead to Ethereum users losing funds due to human error. For example, users sending funds to a smart contract wallet address which was not deployed on a particular chain. @@ -36,13 +36,8 @@ Chain-specific address = "`shortName`" "`:`" "`address`" ### Semantics -``` - -`shortName` is mandatory and MUST be a valid chain short name from https://github.com/ethereum-lists/chains - -`address` is mandatory and MUST be a [ERC-55](./eip-55.md) compatible hexadecimal address - -``` +* `shortName` is mandatory and MUST be a valid chain short name from https://github.com/ethereum-lists/chains +* `address` is mandatory and MUST be a [ERC-55](./eip-55.md) compatible hexadecimal address ### Examples From fb96eca5df44178ada0d1f0fe00fd24d849c37cb Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 30 Aug 2024 20:40:59 -0400 Subject: [PATCH 42/79] Update ERC-7585: fix typo Merged by EIP-Bot. --- ERCS/erc-7585.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7585.md b/ERCS/erc-7585.md index 0e7eedf6b3..ddbd016e93 100644 --- a/ERCS/erc-7585.md +++ b/ERCS/erc-7585.md @@ -13,7 +13,7 @@ requires: 165, 721, 1155 ## Abstract -This proposal introduces a design for `minimum value selection` storage proofs on Merkle trees. The design consists of two main components: +This proposal introduces a design for "minimum value selection" storage proofs on Merkle trees. The design consists of two main components: 1. A hashing algorithm termed MixHash, aimed to replace the commonly used Keccak256 and SHA256 algorithms. 2. Public data storage proofs. This enables anyone to present a proof to a public network, verifying their possession of a copy of specific public data marked by MixHash. @@ -192,7 +192,7 @@ def generateProofWithPow(mixHash, blockHeight,file) noise = noise + 1 m_path = getMerkleTreePath(chunk_hash_array, min_index) - return strorage_proof(mixHash, blockHeight, min_index, m_path, min_chunk,noise) + return storage_proof(mixHash, blockHeight, min_index, m_path, min_chunk,noise) ``` Applying this mechanism increases the cost of generating storage proofs, which deviates from our initial intent to reduce the widespread effective storage of public data. Moreover, heavily relying on a PoW-based economic model may allow Suppliers with significant advantages in PoW through specialized hardware to disrupt the basic participatory nature of the game, reducing the widespread distribution of public data. Therefore, it is advised not to enable the PoW mechanism unless absolutely necessary. @@ -262,12 +262,15 @@ PublicDataProofDemo includes test cases written using Hardhat. ## Reference Implementation PublicDataProof Demo + - A standard reference implementation DMC public data inscription + - Based on public data storage certification, a complete economic model and gameplay has been designed on ETH network and BTC inscription network Learn more background and existing attempts + - DMC Main Chain - CYFS @@ -280,4 +283,3 @@ The design of MixHash can support storage proofs for private files, but this req ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md). - From a0e9b17aa012c521f054bb9944dfc8594952ed49 Mon Sep 17 00:00:00 2001 From: Lukas <36800180+lukasrosario@users.noreply.github.com> Date: Tue, 3 Sep 2024 08:59:20 -0400 Subject: [PATCH 43/79] Update ERC-7677: postopgas callout Merged by EIP-Bot. --- ERCS/erc-7677.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7677.md b/ERCS/erc-7677.md index 3bd5cfdf6a..39c9f0a256 100644 --- a/ERCS/erc-7677.md +++ b/ERCS/erc-7677.md @@ -32,7 +32,9 @@ We define two JSON-RPC methods to be implemented by paymaster web services. Returns stub values to be used in paymaster-related fields of an unsigned user operation for gas estimation. Accepts an unsigned user operation, entrypoint address, chain id, and a context object. Paymaster service providers can define fields that app developers should use in the context object. -This method MAY return paymaster-specific gas values if applicable to the provided EntryPoint version. For example, if provided with EntryPoint v0.7, this method MAY return `paymasterVerificationGasLimit` and `paymasterPostOpGasLimit` values. The wallet SHOULD use these provided gas values when submitting the `UserOperation` to a bundler for gas estimation. +This method MAY return paymaster-specific gas values if applicable to the provided EntryPoint version. For example, if provided with EntryPoint v0.7, this method MAY return `paymasterVerificationGasLimit`. Furthermore, for EntryPoint v0.7, this method MUST return a value for `paymasterPostOpGasLimit`. This is because it is the paymaster that pays the postOpGasLimit, so it cannot trust the wallet to estimate this amount. + +The wallet SHOULD use these provided gas values when submitting the `UserOperation` to a bundler for gas estimation. This method MAY also return a `sponsor` object with a `name` field and an optional `icon` field. The `name` field is the name of the party sponsoring the transaction, and the `icon` field is a URI pointing to an image. Wallet developers MAY choose to display sponsor information to users. The `icon` string MUST be a data URI as defined in [RFC-2397]. The image SHOULD be a square with 96x96px minimum resolution. The image format is RECOMMENDED to be either lossless or vector based such as PNG, WebP or SVG to make the image easy to render on the wallet. Since SVG images can execute Javascript, wallets MUST render SVG images using the `` tag to ensure no untrusted Javascript execution can occur. From 972c598493f8469f9ee95de4bfcb10c7abf7b994 Mon Sep 17 00:00:00 2001 From: Gavin Date: Tue, 3 Sep 2024 22:02:51 +0800 Subject: [PATCH 44/79] Update ERC-7588: Move to Final Merged by EIP-Bot. --- ERCS/erc-7588.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ERCS/erc-7588.md b/ERCS/erc-7588.md index 62ce8f5d9b..212f051034 100644 --- a/ERCS/erc-7588.md +++ b/ERCS/erc-7588.md @@ -4,8 +4,7 @@ title: Blob Transactions Metadata JSON Schema description: Attaching metadata to blobs carried by blob transactions author: Gavin Fu (@gavfu), Leo Wang (@wanglie1986), Bova Chen (@appoipp), Aiden X (@4ever9) discussions-to: https://ethereum-magicians.org/t/erc7588-attaching-metadata-to-blobs-carried-by-blob-transactions/17873 -status: Last Call -last-call-deadline: 2024-09-03 +status: Final type: Standards Track category: ERC created: 2024-01-01 From 7da20a351d8d3c79454ab35b283868166ea81266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernani=20S=C3=A3o=20Thiago?= Date: Tue, 3 Sep 2024 08:20:56 -0600 Subject: [PATCH 45/79] Update ERC-7432: Move to Last Call Merged by EIP-Bot. --- ERCS/erc-7432.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ERCS/erc-7432.md b/ERCS/erc-7432.md index 47c2041e4b..0708c4c36a 100644 --- a/ERCS/erc-7432.md +++ b/ERCS/erc-7432.md @@ -4,7 +4,8 @@ title: Non-Fungible Token Roles description: Role Management for NFTs. Enables accounts to share the utility of NFTs via expirable role assignments. author: Ernani São Thiago (@ernanirst), Daniel Lima (@karacurt) discussions-to: https://ethereum-magicians.org/t/eip-7432-non-fungible-token-roles/15298 -status: Review +status: Last Call +last-call-deadline: 2024-09-17 type: Standards Track category: ERC created: 2023-07-14 @@ -337,7 +338,7 @@ Automatic expiration is implemented via the `grantRole` and `roleExpirationDate` for setting the expiration date, and `roleExpirationDate` allow developers to check whether the role is expired. Since `uint256` is not natively supported by most programming languages, dates are represented as `uint64` on this standard. The maximum UNIX timestamp represented by a `uint64` is about the year `584,942,417,355`, which should be enough to be -considered "permanent". For this reason, it's RECOMMENDED using `type(uint64).max` to support use cases that require a +considered "permanent". For this reason, it's recommended using `type(uint64).max` to support use cases that require a role never to expire. ### Revocable Roles @@ -347,8 +348,8 @@ others, the recipient may require assurance that the role cannot be revoked. The to the `grantRole` function to specify whether a role can be revoked prematurely, enabling the standard to support both use cases. -Regardless of the value of `revocable`, it's RECOMMENDED always to enable the `recipient` to revoke roles, allowing -them to eliminate undesirable assignments. +Regardless of the value of `revocable`, it's recommended always to enable the `recipient` to revoke roles, allowing them +to eliminate undesirable assignments. ### Custom Data From 1aaec254cbbf60ea2dd62ece58d9688ef3174c5e Mon Sep 17 00:00:00 2001 From: Peersky <61459744+peersky@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:22:04 +0300 Subject: [PATCH 46/79] Add ERC: Code Index Merged by EIP-Bot. --- ERCS/erc-7744.md | 118 +++++++++++++++++++++++++++++++++ assets/erc-7744/CodeIndex.sol | 38 +++++++++++ assets/erc-7744/ICodeIndex.sol | 11 +++ 3 files changed, 167 insertions(+) create mode 100644 ERCS/erc-7744.md create mode 100644 assets/erc-7744/CodeIndex.sol create mode 100644 assets/erc-7744/ICodeIndex.sol diff --git a/ERCS/erc-7744.md b/ERCS/erc-7744.md new file mode 100644 index 0000000000..2d48b0bac1 --- /dev/null +++ b/ERCS/erc-7744.md @@ -0,0 +1,118 @@ +--- +eip: 7744 +title: Code Index +description: Global repository of bytecode, enabling developers, auditors, and researchers to find, analyze, and reuse bytecode efficiently. +author: Tim Pechersky (@peersky) +discussions-to: https://ethereum-magicians.org/t/erc-7744-code-index/20569 +status: Draft +type: Standards Track +category: ERC +created: 2024-07-16 +--- + +## Abstract + +This EIP defines a standard interface for indexing smart contracts on Ethereum by their bytecode hash. This enables trustless discovery and verification of contract code, facilitating use cases like bytecode signing, whitelisting, and decentralized distribution mechanisms. + +## Motivation + +Existing contract discovery relies on addresses, which are non-deterministic and can be obfuscated through proxies. Indexing by bytecode hash provides a deterministic and tamper-proof way to identify and verify contract code, enhancing security and trust in the Ethereum ecosystem. + +Consider a security auditor who wants to attest to the integrity of a contract's code. By referencing bytecode hashes, auditors can focus their audit on the bytecode itself, without needing to assess deployment parameters or storage contents. This method verifies the integrity of a contract's codebase without auditing the entire contract state. + +Additionally, bytecode referencing allows whitelist contracts before deployment, allowing developers to get pre-approval for their codebase without disclosing the code itself, or even pre-setup infrastructure that will change it behavior upon adding some determined functionality on chain. + +For developers relying on extensive code reuse, bytecode referencing protects against malicious changes that can occur with address-based referencing through proxies. This builds long-term trust chains extending to end-user applications. + +For decentralized application (dApp) developers, a code index can save gas costs by allowing them to reference existing codebases instead of redeploying them, optimizing resource usage. This can be useful for dApps that rely on extensive re-use of same codebase as own dependencies. + +### Why this registry needs to be an ERC + +The Code Index is essential for trustless and secure smart contract development. By standardizing the interface for indexing contracts by their bytecode, developers can easily integrate this feature into their smart contracts, enhancing the security and trustworthiness of the Ethereum ecosystem. + +Its simplicity and generic nature make it suitable for a wide range of applications. The ability to globally reference the same codebase makes it an ideal candidate for standardization. + +Ultimately, this feature should be incorporated into EIP standards, as it is a fundamental building block for trustless and secure smart contract development. This standard is a step towards this goal. + + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity =0.8.20; + +interface ICodeIndex { + event Indexed(address indexed container, bytes32 indexed codeHash); + error alreadyExists(bytes32 id, address source); + + function register(address container) external; + + function get(bytes32 id) external view returns (address); +} + +/** + * @title Byte Code Indexer Contract + * @notice You can use this contract to index contracts by their bytecode. + * @dev This allows to query contracts by their bytecode instead of addresses. + * @author Tim Pechersky (@Peersky) + */ +contract CodeIndex is ICodeIndex { + mapping(bytes32 => address) private index; + + /** + * @notice Registers a contract in the index by its bytecode hash + * @param container The contract to register + * @dev `msg.codeHash` will be used + * @dev It will revert if the contract is already indexed + */ + function register(address container) external { + address etalon = index[container.codehash]; + if (etalon != address(0)) { + revert alreadyExists(container.codehash, etalon); + } + index[container.codehash] = container; + emit Indexed(container, container.codehash); + } + + /** + * @notice Returns the contract address by its bytecode hash + * @dev returns zero if the contract is not indexed + * @param id The bytecode hash + * @return The contract address + */ + function get(bytes32 id) external view returns (address) { + return index[id]; + } +} + +``` + +### Deployment method + +The `CodeIndex` contract is deployed at: `0xc0D31d398c5ee86C5f8a23FA253ee8a586dA03Ce` using `CREATE2` via the deterministic deployer at `0x4e59b44847b379578588920ca78fbf26c0b4956c` with a salt of `0x220a70730c743a005cfd55180805d2c0d5b8c7695c5496100dcffa91c02befce` is obtained by seeking a vanity address with meaningful name "Code ID (`c0D31d`). + +## Rationale + +**Bytecode over Addresses**: Bytecode is deterministic and can be verified on-chain, while addresses are opaque and mutable. + +**Reverting on re-indexing**: There is small, yet non-zero probability of hash collision attack. Disallowing updates to indexed location of bytecode coupes with this. + +**Simple Interface**: The interface is minimal and focused to maximize composability and ease of implementation. + +**Library Implementation**: Implementing this as a library would limit its impact, making code reuse more difficult and lacking a single, official source of truth. By establishing this as an ERC, we ensure standardization and widespread adoption, driving the ecosystem forward. + +## Reference Implementation + +Reference implementation of the Code Index can be found in the assets folder. There you can find the [interface](../assets/eip-7744/ICodeIndex.sol) and the [implementation](../assets/eip-7744/CodeIndex.sol) of the Code Index. + +## Security Considerations + +**Malicious Code**: The index does NOT guarantee the safety or functionality of indexed contracts. Users MUST exercise caution and perform their own due diligence before interacting with indexed contracts. + +**Storage contents of registered contracts**: The index only refers to the bytecode of the contract, not the storage contents. This means that the contract state is not indexed and may change over time. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/assets/erc-7744/CodeIndex.sol b/assets/erc-7744/CodeIndex.sol new file mode 100644 index 0000000000..bd7a076378 --- /dev/null +++ b/assets/erc-7744/CodeIndex.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity 0.8.20; +import "./ICodeIndex.sol"; + +/** + * @title Byte Code Indexer Contract + * @notice You can use this contract to index contracts by their bytecode. + * @dev This allows to query contracts by their bytecode instead of addresses. + * @author Tim Pechersky (@Peersky) + */ +contract CodeIndex is ICodeIndex { + mapping(bytes32 => address) private index; + + /** + * @notice Registers a contract in the index by its bytecode hash + * @param container The contract to register + * @dev `msg.codeHash` will be used + * @dev It will revert if the contract is already indexed + */ + function register(address container) external { + address etalon = index[container.codehash]; + if (etalon != address(0)) { + revert alreadyExists(container.codehash, etalon); + } + index[container.codehash] = container; + emit Indexed(container, container.codehash); + } + + /** + * @notice Returns the contract address by its bytecode hash + * @dev returns zero if the contract is not indexed + * @param id The bytecode hash + * @return The contract address + */ + function get(bytes32 id) external view returns (address) { + return index[id]; + } +} \ No newline at end of file diff --git a/assets/erc-7744/ICodeIndex.sol b/assets/erc-7744/ICodeIndex.sol new file mode 100644 index 0000000000..aadd4f4f3d --- /dev/null +++ b/assets/erc-7744/ICodeIndex.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity 0.8.20; + +interface ICodeIndex { + event Indexed(address indexed container, bytes32 indexed codeHash); + error alreadyExists(bytes32 id, address source); + + function register(address container) external; + + function get(bytes32 id) external view returns (address); +} \ No newline at end of file From 0fe4e1c19c2dc6c81da1cad5370656cf82c60491 Mon Sep 17 00:00:00 2001 From: Peersky <61459744+peersky@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:28:43 +0300 Subject: [PATCH 47/79] Add ERC: Composable Security Middleware Hooks Merged by EIP-Bot. --- ERCS/erc-7746.md | 101 +++++++++++++ assets/erc-7746/ILayer.sol | 21 +++ assets/erc-7746/README.md | 7 + assets/erc-7746/test/AccessLayers.sol | 21 +++ assets/erc-7746/test/Drainer.sol | 13 ++ assets/erc-7746/test/IVictim.sol | 6 + assets/erc-7746/test/LibAccessLayers.sol | 150 +++++++++++++++++++ assets/erc-7746/test/MockERC20.sol | 17 +++ assets/erc-7746/test/Protected.sol | 30 ++++ assets/erc-7746/test/RateLimitLayer.sol | 36 +++++ assets/erc-7746/test/deploy/drainer.ts | 19 +++ assets/erc-7746/test/deploy/layered_proxy.ts | 40 +++++ assets/erc-7746/test/deploy/simple_layer.ts | 18 +++ assets/erc-7746/test/test.ts | 40 +++++ 14 files changed, 519 insertions(+) create mode 100644 ERCS/erc-7746.md create mode 100644 assets/erc-7746/ILayer.sol create mode 100644 assets/erc-7746/README.md create mode 100644 assets/erc-7746/test/AccessLayers.sol create mode 100644 assets/erc-7746/test/Drainer.sol create mode 100644 assets/erc-7746/test/IVictim.sol create mode 100644 assets/erc-7746/test/LibAccessLayers.sol create mode 100644 assets/erc-7746/test/MockERC20.sol create mode 100644 assets/erc-7746/test/Protected.sol create mode 100644 assets/erc-7746/test/RateLimitLayer.sol create mode 100644 assets/erc-7746/test/deploy/drainer.ts create mode 100644 assets/erc-7746/test/deploy/layered_proxy.ts create mode 100644 assets/erc-7746/test/deploy/simple_layer.ts create mode 100644 assets/erc-7746/test/test.ts diff --git a/ERCS/erc-7746.md b/ERCS/erc-7746.md new file mode 100644 index 0000000000..cf944f6d71 --- /dev/null +++ b/ERCS/erc-7746.md @@ -0,0 +1,101 @@ +--- +eip: 7746 +title: Composable Security Middleware Hooks +description: An interface for composable, runtime security checks in smart contracts. +author: Tim Pechersky (@peersky) +discussions-to: https://ethereum-magicians.org/t/erc-7746-composable-security-middleware-hooks/19471 +status: Draft +type: Standards Track +category: ERC +created: 2024-07-17 +--- + +## Abstract + +This EIP proposes a standard interface, `ILayer`, for implementing composable security layers in smart contracts. These layers act as middleware, enabling runtime validation of function calls before and after execution, independent of the protected contract's logic. This approach facilitates modular security, allowing independent providers to manage and upgrade security layers across multiple contracts. + +## Motivation + +Current smart contract security practices often rely on monolithic validation logic within the contract itself. This can lead to tightly coupled code, making it difficult to isolate and address security concerns. Existing ERCs already are using something that can be seen as specific implementation of such layers wrapping: [ERC-4337](./eip-4337.md) describes requirements to perform validate user operations in a separate contract, and later elaborates same need to paymaster validation, that can be seen as a separate layers of a generic system. +The Security Layers Standard introduces a modular approach, enabling: + +- **Independent Security Providers:** Specialized security providers can focus on developing and maintaining specific security checks. +- **Composable Security:** Layers can be combined to create comprehensive security profiles tailored to individual contract needs. +- **Upgradability:** Security layers can be updated without requiring changes to the protected contract. +- **Flexibility:** Layers can perform a wide range of validation checks, including access control, input sanitization, output verification, and more. + +Having a generalized standard for such layers can help to build more secure and modular systems as well as enable security providers to build generic, service-oriented security oracle solutions. + +## Specification + +A contract implementing the `ILayer` interface MUST provide two functions: + +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity 0.8.20; + +interface ILayer { + /// @notice Validates a function call before execution. + /// @param configuration Layer-specific configuration data. + /// @param selector The function selector being called. + /// @param sender The address initiating the call. + /// @param value The amount of ETH sent with the call (if any). + /// @param data The calldata for the function call. + /// @return beforeCallResult Arbitrary data to be passed to `afterCallValidation`. + /// @dev MUST revert if validation fails. + function beforeCall( + bytes memory configuration, + bytes4 selector, + address sender, + uint256 value, + bytes memory data + ) external returns (bytes memory); + + /// @notice Validates a function call after execution. + /// @param configuration Layer-specific configuration data. + /// @param selector The function selector being called. + /// @param sender The address initiating the call. + /// @param value The amount of ETH sent with the call (if any). + /// @param data The calldata for the function call. + /// @param beforeCallResult The data returned by `beforeCallValidation`. + /// @dev MUST revert if validation fails. + function afterCall( + bytes memory configuration, + bytes4 selector, + address sender, + uint256 value, + bytes memory data, + bytes memory beforeCallResult + ) external; +} + +``` + +A protected contract MAY integrate security layers by calling the `beforeCallValidation` function before executing its logic and the `afterCallValidation` function afterwards. Multiple layers can be registered and executed in a defined order. The protected contract MUST revert if any layer reverts. + +## Rationale + +**Flexibility**: The `layerConfig` parameter allows for layer-specific customization, enabling a single layer implementation to serve multiple contracts with varying requirements. + +**non-static calls**: Layers can maintain their own state, allowing for more complex validation logic (e.g., rate limiting, usage tracking). + +**Strict Validation**: Reverts on validation failure ensure a fail-safe mechanism, preventing execution of potentially harmful transactions. + +**Gas Costs**: Layers naturally will have gas costs associated with their execution. However, the benefits of enhanced security and modularity outweigh these costs, especially as blockchain technology continues to evolve and we expect gas costs to decrease over time. + +## Reference Implementation + +A reference implementation of the `ILayer` interface and a sample protected contract can be found in the repository: +In the [`../assets/eip-7746/ILayer.sol`](../assets/eip-7746/ILayer.sol) a reference interface is provided. + +In this test, a [`Protected.sol`](../assets/eip-7746/test/Protected.sol) contract is protected by a [`RateLimitLayer.sol`](../assets/eip-7746/test/RateLimitLayer.sol) layer. The `RateLimitLayer` implements the `ILayer` interface and enforces a rate which client has configured. +The `Drainer` simulates a vulnerable contract that acts in a malicious way. In the `test.ts` The `Drainer` contract is trying to drain the funds from the `Protected` contract. It is assumed that `Protected` contract has bug that allows partial unauthorized access to the state. +The `RateLimitLayer` is configured to allow only 10 transactions per block from same sender. The test checks that the `Drainer` contract is not able to drain the funds from the `Protected` contract. + +## Security Considerations + +**Layer Trust**: Thoroughly audit and vet any security layer before integrating it into your contract. Malicious layers can compromise contract security. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/assets/erc-7746/ILayer.sol b/assets/erc-7746/ILayer.sol new file mode 100644 index 0000000000..283773b31c --- /dev/null +++ b/assets/erc-7746/ILayer.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity =0.8.20; + +interface ILayer { + function beforeCall( + bytes memory configuration, + bytes4 selector, + address sender, + uint256 value, + bytes memory data + ) external returns (bytes memory); + + function afterCall( + bytes memory configuration, + bytes4 selector, + address sender, + uint256 value, + bytes memory data, + bytes memory beforeCallResult + ) external; +} diff --git a/assets/erc-7746/README.md b/assets/erc-7746/README.md new file mode 100644 index 0000000000..2d1594c300 --- /dev/null +++ b/assets/erc-7746/README.md @@ -0,0 +1,7 @@ +# References for ERC-7746 + +In this directory you can find a reference implementation of the ILayer interface and a sample MockERC20 contract. + +In this test, a [Protected.sol](./test/Protected.sol) contract is protected by a [RateLimitLayer.sol](./test/RateLimitLayer.sol) layer. The RateLimitLayer implements the ILayer interface and enforces a rate which client has configured. +The Drainer simulates a vulnerable contract that acts in a malicious way. In the `test.ts` The Drainer contract is trying to drain the funds from the Protected contract. It is assumed that Protected contract has bug that allows partial unauthorized access to the state. +The RateLimitLayer is configured to allow only 10 transactions per block from same sender. The test checks that the Drainer contract is not able to drain the funds from the Protected contract. \ No newline at end of file diff --git a/assets/erc-7746/test/AccessLayers.sol b/assets/erc-7746/test/AccessLayers.sol new file mode 100644 index 0000000000..c7a08503ed --- /dev/null +++ b/assets/erc-7746/test/AccessLayers.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 + +/** + * Author: @Peersky https://github.com/peersky + */ + +pragma solidity =0.8.20; +import "./LibAccessLayers.sol"; + +abstract contract AccessLayers { + modifier layers( + bytes4 _selector, + address sender, + bytes calldata data, + uint256 value + ) { + bytes[] memory layerReturns = LibAccessLayers.beforeCall(_selector, sender, data, value); + _; + LibAccessLayers.afterCall(_selector, sender, data, value, layerReturns); + } +} diff --git a/assets/erc-7746/test/Drainer.sol b/assets/erc-7746/test/Drainer.sol new file mode 100644 index 0000000000..7eb8d05422 --- /dev/null +++ b/assets/erc-7746/test/Drainer.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: CC0-1.0 +import "./MockERC20.sol"; +pragma solidity =0.8.20; + +contract Drainer { + constructor() {} + + function drain(address payable victim, uint256 cycles) public { + for (uint256 i = 0; i < cycles; i++) { + MockERC20(victim).mint(address(this), 1); + } + } +} diff --git a/assets/erc-7746/test/IVictim.sol b/assets/erc-7746/test/IVictim.sol new file mode 100644 index 0000000000..3320104d6d --- /dev/null +++ b/assets/erc-7746/test/IVictim.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity =0.8.20; + +interface IVictim { + function drainedMethod() external; +} diff --git a/assets/erc-7746/test/LibAccessLayers.sol b/assets/erc-7746/test/LibAccessLayers.sol new file mode 100644 index 0000000000..29d9c3d40d --- /dev/null +++ b/assets/erc-7746/test/LibAccessLayers.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity =0.8.20; +import "../ILayer.sol"; + +library LibAccessLayers { + bytes32 constant ACCESS_LAYERS_STORAGE_POSITION = keccak256("lib.access.layer.storage"); + + struct LayerStruct { + address layerAddess; + bytes4 beforeSig; + bytes4 afterSig; + bytes layerConfigData; + } + + function accessLayersStorage() internal pure returns (LayerStruct[] storage ls) { + bytes32 position = ACCESS_LAYERS_STORAGE_POSITION; + assembly { + ls.slot := position + } + } + + function setLayer( + address layerAddress, + uint256 layerIndex, + bytes memory layerConfigData, + bytes4 beforeCallMethodSignature, + bytes4 afterCallMethodSignature + ) internal { + LayerStruct[] storage ls = accessLayersStorage(); + ls[layerIndex].layerAddess = layerAddress; + ls[layerIndex].layerConfigData = layerConfigData; + ls[layerIndex].beforeSig = beforeCallMethodSignature; + ls[layerIndex].afterSig = afterCallMethodSignature; + } + + function addLayer(LayerStruct memory newLayer) internal { + LayerStruct[] storage ls = accessLayersStorage(); + ls.push(newLayer); + } + + function setLayers(LayerStruct[] memory newLayers) internal { + for (uint256 i = 0; i < newLayers.length; i++) { + addLayer(newLayers[i]); + } + } + + function addLayer( + address layerAddress, + bytes memory layerConfigData, + bytes4 beforeCallMethodSignature, + bytes4 afterCallMethodSignature + ) internal { + LayerStruct[] storage ls = accessLayersStorage(); + LayerStruct memory newLayer = LayerStruct({ + layerAddess: layerAddress, + layerConfigData: layerConfigData, + beforeSig: beforeCallMethodSignature, + afterSig: afterCallMethodSignature + }); + ls.push(newLayer); + } + + function popLayer() internal { + LayerStruct[] storage ls = accessLayersStorage(); + ls.pop(); + } + + function getLayer(uint256 layerIdx) internal view returns (LayerStruct storage) { + LayerStruct[] storage ls = accessLayersStorage(); + return ls[layerIdx]; + } + + function beforeCall( + bytes4 _selector, + address sender, + bytes calldata data, + uint256 value + ) internal returns (bytes[] memory) { + LayerStruct[] storage ls = accessLayersStorage(); + bytes[] memory layerReturns = new bytes[](ls.length); + for (uint256 i = 0; i < ls.length; i++) { + layerReturns[i] = validateLayerBeforeCall(ls[i], _selector, sender, data, value); + } + return layerReturns; + } + + function validateLayerBeforeCall( + LayerStruct storage layer, + bytes4 _selector, + address sender, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { + bytes memory retval = ILayer(layer.layerAddess).beforeCallValidation( + layer.layerConfigData, + _selector, + sender, + value, + data + ); + + return retval; + } + + function afterCall( + bytes4 _selector, + address sender, + bytes calldata data, + uint256 value, + bytes[] memory beforeCallReturns + ) internal { + LayerStruct[] storage ls = accessLayersStorage(); + for (uint256 i = 0; i < ls.length; i++) { + validateLayerAfterCall(ls[ls.length - 1 - i], _selector, sender, data, value, beforeCallReturns[i]); + } + } + + function extractRevertReason(bytes memory revertData) internal pure returns (string memory reason) { + uint l = revertData.length; + if (l < 68) return ""; + uint t; + assembly { + revertData := add(revertData, 4) + t := mload(revertData) // Save the content of the length slot + mstore(revertData, sub(l, 4)) // Set proper length + } + reason = abi.decode(revertData, (string)); + assembly { + mstore(revertData, t) // Restore the content of the length slot + } + } + + function validateLayerAfterCall( + LayerStruct storage layer, + bytes4 _selector, + address sender, + bytes calldata data, + uint256 value, + bytes memory beforeCallReturnValue + ) internal { + ILayer(layer.layerAddess).afterCallValidation( + layer.layerConfigData, + _selector, + sender, + value, + data, + beforeCallReturnValue + ); + } +} diff --git a/assets/erc-7746/test/MockERC20.sol b/assets/erc-7746/test/MockERC20.sol new file mode 100644 index 0000000000..2a78e84c0b --- /dev/null +++ b/assets/erc-7746/test/MockERC20.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: CC0-1.0 +import "@openzeppelin/contracts-upgradable/token/ERC20/extensions/ERC20Burnable.sol"; +import "@openzeppelin/contracts-upgradalbe/access/OwnableUpgradeable.sol"; + +pragma solidity ^0.8.0; + +contract MockERC20 is ERC20Burnable, Ownable { + uint256 numTokens; + + constructor() ERC20("Mock", "MCK") Ownable(msg.sender) {} + + function mint(address to, uint256 amount) public { + require(to != address(0), "MockERC20->mint: Address not specified"); + require(amount != 0, "MockERC20->mint: amount not specified"); + _mint(to, amount); + } +} diff --git a/assets/erc-7746/test/Protected.sol b/assets/erc-7746/test/Protected.sol new file mode 100644 index 0000000000..aebd1bfc32 --- /dev/null +++ b/assets/erc-7746/test/Protected.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity =0.8.20; + +import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import "./AccessLayers.sol"; +import "./LibAccessLayers.sol"; + +contract Protected is TransparentUpgradeableProxy, AccessLayers { + uint256 balance = 10000000 ether; + + constructor( + address initialOwner, + LibAccessLayers.LayerStruct[] memory layers, + address initialImplementation + ) TransparentUpgradeableProxy(initialImplementation, initialOwner, "") { + LibAccessLayers.setLayers(layers); + } + + event Transfer(address from, address to, uint256 amount); + + fallback() external payable override layers(msg.sig, msg.sender, msg.data, msg.value) { + // _delegate(_implementation()); <- this method will not return to solidity :( + (bool success, bytes memory result) = _implementation().delegatecall(msg.data); + require(success, string(result)); + } + + receive() external payable { + // custom function code + } +} diff --git a/assets/erc-7746/test/RateLimitLayer.sol b/assets/erc-7746/test/RateLimitLayer.sol new file mode 100644 index 0000000000..c576ff9f86 --- /dev/null +++ b/assets/erc-7746/test/RateLimitLayer.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity =0.8.20; +import "../ILayer.sol"; + +contract RateLimitLayer is ILayer { + mapping(address => mapping(bytes4 => uint256)) usage; + mapping(address => mapping(bytes4 => uint256)) usageUpdatedAtBlock; + + function beforeCallValidation( + bytes memory, + bytes4 messageSig, + address, + uint256, + bytes memory + ) public returns (bytes memory) { + if (usageUpdatedAtBlock[msg.sender][messageSig] != block.number) { + usage[msg.sender][messageSig] = 0; + usageUpdatedAtBlock[msg.sender][messageSig] = block.number; + } else { + usage[msg.sender][messageSig] += 1; + } + return ""; + } + + function afterCallValidation( + bytes memory layerConfig, + bytes4 messageSig, + address, + uint256, + bytes memory, + bytes memory + ) public view { + uint256 blockQuota = uint256(bytes32(layerConfig)); + require(usage[msg.sender][messageSig] < blockQuota, "Rate limited"); + } +} diff --git a/assets/erc-7746/test/deploy/drainer.ts b/assets/erc-7746/test/deploy/drainer.ts new file mode 100644 index 0000000000..7f67b20d28 --- /dev/null +++ b/assets/erc-7746/test/deploy/drainer.ts @@ -0,0 +1,19 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + + const { deployer, owner } = await getNamedAccounts(); + + await deploy("Drainer", { + from: deployer, + args: [], + skipIfAlreadyDeployed: true, + }); +}; + +export default func; +func.dependencies = ["layer_proxy"]; +func.tags = ["poc", "drainer"]; diff --git a/assets/erc-7746/test/deploy/layered_proxy.ts b/assets/erc-7746/test/deploy/layered_proxy.ts new file mode 100644 index 0000000000..ed7c223088 --- /dev/null +++ b/assets/erc-7746/test/deploy/layered_proxy.ts @@ -0,0 +1,40 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { MockERC20, RateLimitLayer } from "../types"; +import { ethers } from "hardhat"; +import { LibAccessLayers } from "../types/src/MockERC20"; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + + const { deployer, owner } = await getNamedAccounts(); + + const simpleLayer = await deployments.get("RateLimitLayer"); + const simpleLayerContract = (await ethers.getContractAt(simpleLayer.abi, simpleLayer.address)) as RateLimitLayer; + + let layer: LibAccessLayers.LayerStructStruct = { + layerAddess: simpleLayer.address, + beforeSig: simpleLayerContract.interface.getSighash(simpleLayerContract.interface.functions["beforeCallValidation(bytes,bytes4,address,uint256,bytes)"]), + afterSig: simpleLayerContract.interface.getSighash( + simpleLayerContract.interface.functions["afterCallValidation(bytes,bytes4,address,uint256,bytes,bytes)"] + ), + layerConfigData: ethers.utils.defaultAbiCoder.encode(["uint256"], [10]), + }; + + const result = await deploy("MockERC20", { + from: deployer, + args: [], + skipIfAlreadyDeployed: true, + }); + + const lp = await deploy("MockERC20", { + from: deployer, + args: [owner, [layer], result.address], + skipIfAlreadyDeployed: true, + }); +}; + +export default func; +func.dependencies = ["simple_layer"]; +func.tags = ["poc", "layer_proxy"]; diff --git a/assets/erc-7746/test/deploy/simple_layer.ts b/assets/erc-7746/test/deploy/simple_layer.ts new file mode 100644 index 0000000000..a4baa8fc61 --- /dev/null +++ b/assets/erc-7746/test/deploy/simple_layer.ts @@ -0,0 +1,18 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + + const { deployer } = await getNamedAccounts(); + + await deploy("RateLimitLayer", { + from: deployer, + args: [], + skipIfAlreadyDeployed: true, + }); +}; + +export default func; +func.tags = ["poc", "simple_layer"]; diff --git a/assets/erc-7746/test/test.ts b/assets/erc-7746/test/test.ts new file mode 100644 index 0000000000..94b469043b --- /dev/null +++ b/assets/erc-7746/test/test.ts @@ -0,0 +1,40 @@ +/* global ethers */ + +import { deployments, ethers } from "hardhat"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; + +import { expect } from "chai"; +import { Drainer, Protected, MockERC20 } from "../types"; + +const setupTest = deployments.createFixture(async ({ deployments, getNamedAccounts, ethers: _eth }, options) => { + const { deployer, owner } = await getNamedAccounts(); + await deployments.fixture(["poc"]); + console.warn(deployer, owner); + const c = await deployments.get("Protected"); + const d = await deployments.get("Drainer"); + return { + owner, + deployer, + victim: (await ethers.getContractAt(c.abi, c.address)) as Protected, + attacker: (await ethers.getContractAt(d.abi, d.address)) as Drainer, + }; +}); + +describe("test drainage", async function () { + let env: { + owner: string; + deployer: string; + victim: Protected; + attacker: Drainer; + }; + beforeEach(async function () { + env = await setupTest(); + }); + it("succeeds below 10 transactions", async () => { + await expect(env.attacker.drain(env.victim.address, 1)).to.emit(env.victim, "Transfer"); + }); + it("fails beyond 10 transactions", async () => { + await expect(env.attacker.drain(env.victim.address, 11)).to.be.revertedWith("Rate limited"); + }); +}); From ab5518bd3884b89ed0f3f76e105823f0b89ae09e Mon Sep 17 00:00:00 2001 From: Liaoyuan Date: Tue, 3 Sep 2024 22:43:26 +0800 Subject: [PATCH 48/79] Update ERC-7627: Move to Review Merged by EIP-Bot. --- ERCS/erc-7627.md | 140 +++++++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/ERCS/erc-7627.md b/ERCS/erc-7627.md index e035415ca6..f9c6428703 100644 --- a/ERCS/erc-7627.md +++ b/ERCS/erc-7627.md @@ -1,10 +1,10 @@ --- eip: 7627 title: Secure Messaging Protocol -description: A solution implementing end-to-end encryption for sending messages between users. +description: End-to-end encryption for sending messages between users. author: Chen Liaoyuan (@chenly) discussions-to: https://ethereum-magicians.org/t/erc-7627-secure-messaging-protocol/18761 -status: Draft +status: Review type: Standards Track category: ERC created: 2024-02-19 @@ -16,7 +16,7 @@ This proposal implements the capability to securely exchange encrypted messages ## Motivation -With the emergence of Layer 2 chains featuring sub-second block times and the introduction of account abstraction, the use of end-to-end encrypted communication has facilitated the proliferation of real-time communication and online chat dApps. Leveraging asymmetric encryption now enables the establishment of decentralized, end-to-end interoperable messaging protocols as a standard. +With the emergence of Layer 2 chains featuring sub-second block times and the introduction of account abstraction, the use of end-to-end encrypted communication has facilitated the proliferation of real-time communication and online chat dApps. Providing a unified interface enables easy integration of encrypted communication into smart contracts, thereby fostering innovation. Standardization promotes interoperability, facilitating seamless communication across platforms. ## Specification @@ -40,56 +40,71 @@ pragma solidity ^0.8.0; interface IERC7627 { enum PublicKeyAlgorithm { ECDSA, ED25519, X25519 } + + struct PublicKey { + bytes public_key; + uint64 valid_before; + PublicKeyAlgorithm algorithm; + } // Events - - /** - * @dev Event emitted when a message is sent. - * @param from The address of the sender. - * @param to The address of the recipient. - * @param sessionId The session ID of the message. - * @param encryptedMessage The encrypted message. - */ - event MessageSent(address indexed from, address indexed to, bytes32 sessionId, bytes encryptedMessage); - - /** - * @dev Event emitted when a user updates their public key. - * @param user The address of the user. - * @param newPublicKey The new public key of the user. - * @param algorithm The algorithm used for the public key. - */ - event PublicKeyUpdated(address indexed user, bytes newPublicKey, PublicKeyAlgorithm algorithm); + /** + * @notice Event emitted when a message is sent between users. + * @param from The address of the sender + * @param to The address of the recipient + * @param keyIndex The index of the public key used to encrypt the message + * @param sessionId The session ID for the communication + * @param encryptedMessage The encrypted message in bytes + */ + event MessageSent(address indexed from, address indexed to, bytes32 indexed keyIndex, bytes32 sessionId, bytes encryptedMessage); + + /** + * @notice Event emitted when a user's public key is updated. + * @param user The address of the user whose public key is updated + * @param keyIndex The index of the public key being updated + * @param newPublicKey The new public key data + */ + event PublicKeyUpdated(address indexed user, bytes32 indexed keyIndex, PublicKey newPublicKey); // Functions - /** - * @dev Function to update a user's public key. - * @param _publicKey The public key of the user. - * @param _algorithm The algorithm used for the public key. - */ - function updatePublicKey(bytes calldata _publicKey, PublicKeyAlgorithm _algorithm) external; - - /** - * @dev Function to send an encrypted message from one user to another. - * @param _to The address of the recipient. - * @param _sessionId The session ID of the message. - * @param _encryptedMessage The encrypted message. - */ - function sendMessage(address _to, bytes32 _sessionId, bytes calldata _encryptedMessage) external; - - /** - * @dev Function to retrieve a user's public key and algorithm. - * @param _user The address of the user. - * @return publicKey The public key of the user. - * @return algorithm The algorithm used for the public key. - */ - function getUserPublicKey(address _user) external view returns (bytes memory publicKey, PublicKeyAlgorithm algorithm); + /** + * @notice Updates the public key for the sender. + * @param _keyIndex The index of the key to be updated + * @param _publicKey The new public key data + */ + function updatePublicKey(bytes32 _keyIndex, PublicKey memory _publicKey) external; + + /** + * @notice Sends an encrypted message to a specified address. + * @param _to The recipient's address + * @param _keyIndex The index of the public key used to encrypt the message + * @param _sessionId The session ID for the communication + * @param _encryptedMessage The encrypted message in bytes + */ + function sendMessage(address _to, bytes32 _keyIndex, bytes32 _sessionId, bytes calldata _encryptedMessage) external; + + /** + * @notice Retrieves a public key for a specific user and key index. + * @param _user The address of the user + * @param _keyIndex The index of the key to retrieve + * @return The public key data associated with the user and key index + */ + function getUserPublicKey(address _user, bytes32 _keyIndex) external view returns (PublicKey memory); } ``` ## Rationale -Traditional messaging lacks security and transparency for blockchain communication. The choice of asymmetric encryption ensures the confidentiality and integrity of messages, which is why we opted for this encryption method. Providing a unified interface enables easy integration of encrypted communication into smart contracts, thereby fostering innovation. Encrypted messaging guarantees adherence to best practices in data security. Due to security reasons, public keys need to be regularly updated, hence we have added a feature that allows users to autonomously update their public keys. The interface supports various encryption methods, enhancing adaptability. Event tracking enhances the observability and auditability of the contract, aiding compliance efforts. Standardization promotes interoperability, facilitating seamless communication across platforms. +### Event Emission for Off-Chain Integration +By emitting events when messages are sent or public keys are updated, the implementation facilitates seamless integration with off-chain dApps. This enables these dApps to easily track and display the latest messages and updates, ensuring real-time responsiveness and enhancing user interaction. + +### End-to-End Encryption Security +The design ensures that only the owner of an address can update their public key. This restriction preserves the integrity of the end-to-end encryption, making sure that only the intended recipient can decrypt and read the messages, thereby securing communication. + +### Session ID for Conversation Organization +The use of session IDs in message transactions allows multiple messages to be grouped under specific conversations. This feature is crucial for organizing and managing discussions within a dApp, providing users with a coherent and structured messaging experience. + ## Reference Implementation @@ -98,34 +113,34 @@ pragma solidity ^0.8.0; contract ERC7627 { + /// @dev Enum to specify the algorithm used for the public key. enum PublicKeyAlgorithm { ECDSA, ED25519, X25519 } - struct UserInfo { - bytes publicKey; - PublicKeyAlgorithm algorithm; + /// @dev Structure to represent a user's public key. + struct PublicKey { + bytes public_key; + uint64 valid_before; + PublicKeyAlgorithm algorithm; } - mapping(address => UserInfo) public pk; + /// @dev Mapping to store public keys for each address. The mapping is by user address and a unique key index. + mapping(address => mapping(bytes32 => PublicKey)) public pk; - event MessageSent(address indexed from, address indexed to, bytes32 sessionId, bytes encryptedMessage); - event PublicKeyUpdated(address indexed user, bytes newPublicKey, PublicKeyAlgorithm algorithm); + event MessageSent(address indexed from, address indexed to, bytes32 indexed keyIndex, bytes32 sessionId, bytes encryptedMessage); - // Function to register a user with their public key - function updatePublicKey(bytes calldata _publicKey, PublicKeyAlgorithm _algorithm) external { - pk[msg.sender].publicKey = _publicKey; - pk[msg.sender].algorithm = _algorithm; - emit PublicKeyUpdated(msg.sender, _publicKey, _algorithm); + event PublicKeyUpdated(address indexed user, bytes32 indexed keyIndex, PublicKey newPublicKey); + + function updatePublicKey(bytes32 _keyIndex, PublicKey memory _publicKey) external { + pk[msg.sender][_keyIndex] = _publicKey; + emit PublicKeyUpdated(msg.sender, _keyIndex, _publicKey); } - // Function to send an encrypted message from one user to another - function sendMessage(address _to, bytes32 _sessionId, bytes calldata _encryptedMessage) external { - emit MessageSent(msg.sender, _to, _sessionId, _encryptedMessage); + function sendMessage(address _to, bytes32 _keyIndex, bytes32 _sessionId, bytes calldata _encryptedMessage) external { + emit MessageSent(msg.sender, _to, _keyIndex, _sessionId, _encryptedMessage); } - // Function to retrieve a user's public key - function getUserPublicKey(address _user) external view returns (bytes memory, PublicKeyAlgorithm) { - UserInfo memory userInfo = pk[_user]; - return (userInfo.publicKey, userInfo.algorithm); + function getUserPublicKey(address _user, bytes32 _keyIndex) external view returns (PublicKey memory) { + return pk[_user][_keyIndex]; } } ``` @@ -141,9 +156,6 @@ To maintain message confidentiality, the content of sent messages must be strict #### Key Management and Protection Robust key management and protection measures are necessary for both user public and private keys. Ensure secure storage and transmission of keys to prevent leakage and tampering. Employ multi-factor authentication and key rotation strategies to enhance key security and regularly assess key management processes to mitigate potential security risks. -#### Auditing and Monitoring -Implement auditing and monitoring mechanisms to track message sending and receiving, as well as key usage. Promptly identify anomalous activities and potential security threats and take appropriate response measures. Record critical operations and events for security incident investigation and traceability purposes. - ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md) From 95258c8b3667e3adbf6408839a255b8f56c78d5c Mon Sep 17 00:00:00 2001 From: Francesco Sullo Date: Tue, 3 Sep 2024 07:43:54 -0700 Subject: [PATCH 49/79] Update ERC-7656: Move to Review Merged by EIP-Bot. --- ERCS/erc-7656.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ERCS/erc-7656.md b/ERCS/erc-7656.md index bceea4f3b7..b91e771d0c 100644 --- a/ERCS/erc-7656.md +++ b/ERCS/erc-7656.md @@ -4,7 +4,7 @@ title: Generalized Token-Linked Services description: Define a registry for generic services linked to a specific NFT author: Francesco Sullo (@sullof) discussions-to: https://ethereum-magicians.org/t/variation-to-erc6551-to-deploy-any-kind-of-contract-linked-to-an-nft/19223 -status: Draft +status: Review type: Standards Track category: ERC created: 2024-03-15 @@ -116,11 +116,7 @@ ERC-1167 Footer (15 bytes) Any contract created using a `ERC7656Registry` SHOULD implement the `IERC7656Service` interface: ```solidity -<<<<<<< HEAD interface IERC7656Service { -======= -interface IERC7656Linked { ->>>>>>> master /** * @notice Returns the token linked to the contract * @return chainId The chainId of the token From 920a06828dc5e717e78774884b1eee7a6b2531c3 Mon Sep 17 00:00:00 2001 From: Liaoyuan Date: Tue, 3 Sep 2024 22:45:08 +0800 Subject: [PATCH 50/79] Update ERC-7628: Move to Review Merged by EIP-Bot. --- ERCS/erc-7628.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7628.md b/ERCS/erc-7628.md index c348fa4850..ff0a1398ea 100644 --- a/ERCS/erc-7628.md +++ b/ERCS/erc-7628.md @@ -4,7 +4,7 @@ title: ERC-721 Ownership Shares Extension description: Introduces ownership shares to ERC-721 tokens, allowing for queryable, transferable, and approvable fractional ownership. author: Chen Liaoyuan (@chenly) discussions-to: https://ethereum-magicians.org/t/erc-7628-erc-721-ownership-shares-extension/18744 -status: Draft +status: Review type: Standards Track category: ERC created: 2024-02-20 @@ -13,7 +13,7 @@ requires: 721 ## Abstract -The proposal introduces an attribute of ownership and profit share quantities for each token under an NFT. This attribute signifies a stake in the ownership and profit rights associated with the NFT's specific privileges, enabling the querying, transferring, and approval of these shares, thereby making the shares represented by each token applicable in a broader range of use cases. +This proposal introduces an attribute of ownership and profit share quantities for each token under an NFT. This attribute signifies a stake in the ownership and profit rights associated with the NFT's specific privileges, enabling the querying, transferring, and approval of these shares, thereby making the shares represented by each token applicable in a broader range of use cases. ## Motivation From 2b8a2fa51bc45b039caee56b6640be89e6de94fd Mon Sep 17 00:00:00 2001 From: Lukas <36800180+lukasrosario@users.noreply.github.com> Date: Wed, 4 Sep 2024 06:51:18 -0400 Subject: [PATCH 51/79] Update ERC-7677: Move to Review Merged by EIP-Bot. --- ERCS/erc-7677.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ERCS/erc-7677.md b/ERCS/erc-7677.md index 39c9f0a256..e6dce38f95 100644 --- a/ERCS/erc-7677.md +++ b/ERCS/erc-7677.md @@ -4,8 +4,7 @@ title: Paymaster Web Service Capability description: A way for apps to communicate with smart wallets about paymaster web services author: Lukas Rosario (@lukasrosario), Dror Tirosh (@drortirosh), Wilson Cusack (@wilsoncusack), Kristof Gazso (@kristofgazso), Hazim Jumali (@hazim-j) discussions-to: https://ethereum-magicians.org/t/erc-7677-paymaster-web-service-capability/19530 -status: Last Call -last-call-deadline: 2024-09-05 +status: Review type: Standards Track category: ERC created: 2024-04-03 @@ -30,7 +29,7 @@ We define two JSON-RPC methods to be implemented by paymaster web services. #### `pm_getPaymasterStubData` -Returns stub values to be used in paymaster-related fields of an unsigned user operation for gas estimation. Accepts an unsigned user operation, entrypoint address, chain id, and a context object. Paymaster service providers can define fields that app developers should use in the context object. +Returns stub values to be used in paymaster-related fields of an unsigned user operation for gas estimation. Accepts an unsigned user operation, entrypoint address, chain id, and a context object. Paymaster service providers can define fields that app developers should use in the context object. This method MAY return paymaster-specific gas values if applicable to the provided EntryPoint version. For example, if provided with EntryPoint v0.7, this method MAY return `paymasterVerificationGasLimit`. Furthermore, for EntryPoint v0.7, this method MUST return a value for `paymasterPostOpGasLimit`. This is because it is the paymaster that pays the postOpGasLimit, so it cannot trust the wallet to estimate this amount. @@ -67,14 +66,14 @@ type GetPaymasterStubDataParams = [ ]; type GetPaymasterStubDataResult = { - sponsor?: { name: string; icon?: string } // Sponsor info - paymaster?: string // Paymaster address (entrypoint v0.7) + sponsor?: { name: string; icon?: string }; // Sponsor info + paymaster?: string; // Paymaster address (entrypoint v0.7) paymasterData?: string; // Paymaster data (entrypoint v0.7) paymasterVerificationGasLimit?: `0x${string}`; // Paymaster validation gas (entrypoint v0.7) paymasterPostOpGasLimit?: `0x${string}`; // Paymaster post-op gas (entrypoint v0.7) paymasterAndData?: string; // Paymaster and data (entrypoint v0.6) isFinal?: boolean; // Indicates that the caller does not need to call pm_getPaymasterData -} +}; ``` ###### `pm_getPaymasterStubData` Example Parameters @@ -90,7 +89,7 @@ type GetPaymasterStubDataResult = { "verificationGasLimit": "0x...", "preVerificationGas": "0x...", "maxFeePerGas": "0x...", - "maxPriorityFeePerGas": "0x...", + "maxPriorityFeePerGas": "0x..." }, "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", "0x2105", @@ -188,10 +187,10 @@ type GetPaymasterDataParams = [ ]; type GetPaymasterDataResult = { - paymaster?: string // Paymaster address (entrypoint v0.7) + paymaster?: string; // Paymaster address (entrypoint v0.7) paymasterData?: string; // Paymaster data (entrypoint v0.7) paymasterAndData?: string; // Paymaster and data (entrypoint v0.6) -} +}; ``` ###### `pm_getPaymasterData` Example Parameters @@ -207,7 +206,7 @@ type GetPaymasterDataResult = { "verificationGasLimit": "0x...", "preVerificationGas": "0x...", "maxFeePerGas": "0x...", - "maxPriorityFeePerGas": "0x...", + "maxPriorityFeePerGas": "0x..." }, "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", "0x2105", @@ -305,6 +304,7 @@ The wallet will then make the above paymaster RPC calls to the URLs specified in #### Wallet Implementation To conform to this specification, smart wallets that wish to leverage app-sponsored transactions: + 1. MUST indicate to apps that they can communicate with paymaster web services via their response to an [EIP-5792](./eip-5792.md) `wallet_getCapabilities` call. 2. SHOULD make calls to and use the values returned by the paymaster service specified in the capabilities field of an [EIP-5792](./eip-5792.md) `wallet_sendCalls` call. An example of an exception is a wallet that allows users to select a paymaster provided by the wallet. Since there might be cases in which the provided paymaster is ultimately not used—either due to service failure or due to a user selecting a different, wallet-provided paymaster—applications MUST NOT assume that the paymaster it provides to a wallet is the entity that pays for transaction fees. @@ -313,7 +313,7 @@ To conform to this specification, smart wallets that wish to leverage app-sponso ```typescript type PaymasterServiceCapability = { supported: boolean; -} +}; ``` ###### `wallet_getCapabilities` Example Response @@ -323,7 +323,7 @@ type PaymasterServiceCapability = { "0x2105": { "paymasterService": { "supported": true - }, + } }, "0x14A34": { "paymasterService": { @@ -385,4 +385,4 @@ This flow would allow developers to keep their paymaster service API keys secret ## Copyright -Copyright and related rights waived via [CC0](../LICENSE.md). \ No newline at end of file +Copyright and related rights waived via [CC0](../LICENSE.md). From 991debbee9fa44f35c5579376aa640892ca57a04 Mon Sep 17 00:00:00 2001 From: Francesco Sullo Date: Thu, 5 Sep 2024 07:42:31 -0700 Subject: [PATCH 52/79] Update ERC-7656: Fix wording, using service instead of account, when needed Merged by EIP-Bot. --- ERCS/erc-7656.md | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/ERCS/erc-7656.md b/ERCS/erc-7656.md index b91e771d0c..8083137097 100644 --- a/ERCS/erc-7656.md +++ b/ERCS/erc-7656.md @@ -61,15 +61,15 @@ interface IERC7656Registry { error CreationFailed(); /** - * @notice Creates a token linked account for a non-fungible token. - * If account has already been created, returns the account address without calling create2. + * @notice Creates a token linked service for a non-fungible token. + * If the service has already been created, returns the service address without calling create2. * @param implementation The address of the implementation contract * @param salt The salt to use for the create2 operation - * @param chainId The chain id of the chain where the account is being created + * @param chainId The chain id of the chain where the service is being created * @param tokenContract The address of the token contract * @param tokenId The id of the token * Emits Created event. - * @return account The address of the token linked account + * @return service The address of the token linked service */ function create( address implementation, @@ -77,16 +77,16 @@ interface IERC7656Registry { uint256 chainId, address tokenContract, uint256 tokenId - ) external returns (address account); + ) external returns (address service); /** - * @notice Returns the computed token linked account address for a non-fungible token. + * @notice Returns the computed token linked service address for a non-fungible token. * @param implementation The address of the implementation contract * @param salt The salt to use for the create2 operation - * @param chainId The chain id of the chain where the account is being created + * @param chainId The chain id of the chain where the service is being created * @param tokenContract The address of the token contract * @param tokenId The id of the token - * @return account The address of the token linked account + * @return service The address of the token linked service */ function compute( address implementation, @@ -94,15 +94,15 @@ interface IERC7656Registry { uint256 chainId, address tokenContract, uint256 tokenId - ) external view returns (address account); + ) external view returns (address service); } ``` Any `ERC7656Registry` implementation MUST support the `IERC7656Registry`'s interface ID, i.e., `0xc6bdc908`. -Similarly to [ERC-6551](./eip-6551.md), The registry MUST deploy each token linked account as an [ERC-1167](./eip-1167.md) minimal proxy with immutable constant data appended to the bytecode. +Similarly to [ERC-6551](./eip-6551.md), The registry MUST deploy each token linked service as an [ERC-1167](./eip-1167.md) minimal proxy with immutable constant data appended to the bytecode. -The deployed bytecode of each token bound account MUST have the following structure: +The deployed bytecode of each token bound service MUST have the following structure: ``` ERC-1167 Header (10 bytes) (20 bytes) @@ -116,6 +116,7 @@ ERC-1167 Footer (15 bytes) Any contract created using a `ERC7656Registry` SHOULD implement the `IERC7656Service` interface: ```solidity +// InterfaceId 0xfc0c546a interface IERC7656Service { /** * @notice Returns the token linked to the contract @@ -189,12 +190,12 @@ contract ERC7656Registry is IERC7656Registry { mstore(0x01, shl(96, address())) // registry address mstore(0x15, salt) // salt - // Compute account address + // Compute service address let computed := keccak256(0x00, 0x55) - // If the account has not yet been deployed + // If the service has not yet been deployed if iszero(extcodesize(computed)) { - // Deploy account contract + // Deploy service contract let deployed := create2(0, 0x55, 0xb7, salt) // Revert if the deployment fails @@ -203,7 +204,7 @@ contract ERC7656Registry is IERC7656Registry { revert(0x1c, 0x04) } - // Store account address in memory before salt and chainId + // Store service address in memory before salt and chainId mstore(0x6c, deployed) // Emit the Created event @@ -216,11 +217,11 @@ contract ERC7656Registry is IERC7656Registry { tokenId ) - // Return the account address + // Return the service address return(0x6c, 0x20) } - // Otherwise, return the computed account address + // Otherwise, return the computed service address mstore(0x00, shr(96, shl(96, computed))) return(0x00, 0x20) } @@ -247,10 +248,10 @@ contract ERC7656Registry is IERC7656Registry { mstore(0x01, shl(96, address())) // registry address mstore(0x15, salt) // salt - // Store computed account address in memory + // Store computed service address in memory mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55)))) - // Return computed account address + // Return computed service address return(0x00, 0x20) } } From 8082e27c5db9dbb02f659498039d9f1b8f42eece Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Fri, 6 Sep 2024 11:27:45 -0400 Subject: [PATCH 53/79] Remove polyfill. (#620) The `polyfill.io` domain was taken over by a malicious actor, and now injects code that redirects to unrelated websites. References: Reported-By: Elliott Green --- _includes/head.html | 1 - 1 file changed, 1 deletion(-) diff --git a/_includes/head.html b/_includes/head.html index bc8a94533a..d388a866fa 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -43,7 +43,6 @@ {%- feed_meta -%} - + + + + + + Info + + + +

+ +
+
+ + + + Mint + + + + + + + + + +

+ +
+

Use this to mint your own tokens.

+
+
+ + \ No newline at end of file diff --git a/assets/erc-7738/tokenscript/info.html b/assets/erc-7738/tokenscript/info.html new file mode 100644 index 0000000000..9755f14073 --- /dev/null +++ b/assets/erc-7738/tokenscript/info.html @@ -0,0 +1,181 @@ + +
+

ERC-7738 registry

+ +

Contract

+
+ +

Order #

+
+ +

ScriptURI

+
+ +

ENS

+
+ +

Name

+
+ +

Authenticated by Owner

+
+ +
+ + \ No newline at end of file diff --git a/assets/erc-7738/tokenscript/onboard.html b/assets/erc-7738/tokenscript/onboard.html new file mode 100644 index 0000000000..f5e19e4f6b --- /dev/null +++ b/assets/erc-7738/tokenscript/onboard.html @@ -0,0 +1,221 @@ + +

Create a new script mapping for a contract. Input the contract address and the scriptURI

+

+
+

Contract Address

+ + Not a valid contract + +
+
+

ScriptURI

+ + Not a valid URL + +
+ + +

+ \ No newline at end of file diff --git a/assets/erc-7738/tokenscript/out/tokenscript.tsml b/assets/erc-7738/tokenscript/out/tokenscript.tsml new file mode 100644 index 0000000000..6b7762175c --- /dev/null +++ b/assets/erc-7738/tokenscript/out/tokenscript.tsml @@ -0,0 +1,1163 @@ + + + + + ERC-7738 Registry Token + + + ERC-7738 Registry Tokens + + + + + 0x0077380bCDb2717C9640e892B9d5Ee02Bb5e0682 + + + [ + { + "name": "setScriptURI", + "inputs": [ + { + "internalType": "address", + "name": "contractAddressLocal", + "type": "address" + }, + { + "internalType": "string[]", + "name": "scriptURILocal", + "type": "string[]" + } + ], + "outputs": [ + + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "name": "updateScriptURI", + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "scriptURILocal", + "type": "string" + } + ], + "outputs": [ + + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + + + + + + + + + + + Info + + + + + +
+

ERC-7738 registry

+ +

Contract

+
+ +

Order #

+
+ +

ScriptURI

+
+ +

ENS

+
+ +

Name

+
+ +

Authenticated by Owner

+
+ +
+ +
+
+ + + + Update ScriptURI + + + + + + + + + + + + + +

Create a new script mapping for a contract. Input the contract address and the scriptURI

+

+
+

Current ScriptURI

+
+
+
+

+
+

ScriptURI

+ + Not a valid URL + +
+ + +

+
+
+ + + + Set Name + + + + + + + + + + + + + +

Add a name for your script entry

+

+
+

Current Name

+
+
+
+

+
+

Name

+ +
+ +

+
+
+ + + + Set Icon + + + + + + + + + + + + + +
+

Set an icon for your script entry

+

(note, you must upload the icon yourself and provide the URI here)

+
+

+
+

Current Icon

+
+
+
+

+
+

Icon URL

+ + Not a valid URL + +
+ + +

+
+
+ + + + Set ScriptURI + + + + + + + + + + + + + + +

Create a new script mapping for a contract. Input the contract address and the scriptURI

+

+
+

Contract Address

+ + Not a valid contract + +
+
+

ScriptURI

+ + Not a valid URL + +
+ + +

+
+
+
+ + + 1.3.6.1.4.1.1466.115.121.1.36 + + + + totalSupply + + + + + + + + +
\ No newline at end of file diff --git a/assets/erc-7738/tokenscript/setIcon.html b/assets/erc-7738/tokenscript/setIcon.html new file mode 100644 index 0000000000..5497415e1c --- /dev/null +++ b/assets/erc-7738/tokenscript/setIcon.html @@ -0,0 +1,226 @@ + +
+

Set an icon for your script entry

+

(note, you must upload the icon yourself and provide the URI here)

+
+

+
+

Current Icon

+
+
+
+

+
+

Icon URL

+ + Not a valid URL + +
+ + +

+ \ No newline at end of file diff --git a/assets/erc-7738/tokenscript/setName.html b/assets/erc-7738/tokenscript/setName.html new file mode 100644 index 0000000000..6f5858a163 --- /dev/null +++ b/assets/erc-7738/tokenscript/setName.html @@ -0,0 +1,165 @@ + +

Add a name for your script entry

+

+
+

Current Name

+
+
+
+

+
+

Name

+ +
+ +

+ \ No newline at end of file diff --git a/assets/erc-7738/tokenscript/tokenscript.xml b/assets/erc-7738/tokenscript/tokenscript.xml new file mode 100644 index 0000000000..d7a46fcc42 --- /dev/null +++ b/assets/erc-7738/tokenscript/tokenscript.xml @@ -0,0 +1,170 @@ + + + + + + ERC-7738 Registry Token + + + ERC-7738 Registry Tokens + + + + + 0x0077380bCDb2717C9640e892B9d5Ee02Bb5e0682 + + + + + + + + + + + + Info + + + + + + + + + + Update ScriptURI + + + + + + + + + + + + + + + + + + Set Name + + + + + + + + + + + + + + + + + + Set Icon + + + + + + + + + + + + + + + + + + Set ScriptURI + + + + + + + + + + + + + + + + + + + 1.3.6.1.4.1.1466.115.121.1.36 + + + + totalSupply + + + + + + + + + \ No newline at end of file diff --git a/assets/erc-7738/tokenscript/updateScript.html b/assets/erc-7738/tokenscript/updateScript.html new file mode 100644 index 0000000000..7a5e8341dc --- /dev/null +++ b/assets/erc-7738/tokenscript/updateScript.html @@ -0,0 +1,191 @@ + +

Create a new script mapping for a contract. Input the contract address and the scriptURI

+

+
+

Current ScriptURI

+
+
+
+

+
+

ScriptURI

+ + Not a valid URL + +
+ + +

+ \ No newline at end of file From cea07d31de1713f653a7089568b0d83dc1920b38 Mon Sep 17 00:00:00 2001 From: Vidor <1101164+V1d0r@users.noreply.github.com> Date: Fri, 13 Sep 2024 11:34:49 +0100 Subject: [PATCH 57/79] Update ERC-7578: Fix permissions on set properties Merged by EIP-Bot. --- ERCS/erc-7578.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/ERCS/erc-7578.md b/ERCS/erc-7578.md index fa520d71d6..9acb4fbb37 100644 --- a/ERCS/erc-7578.md +++ b/ERCS/erc-7578.md @@ -151,14 +151,28 @@ contract ERC7578 is ERC721, IERC7578 { mapping(uint256 tokenId => Properties) private _properties; /** - * @notice Initializes the [ERC-721](./eip-721.md) dependency contract by setting a `name` and a `symbol` to the token collection + * @notice Initializes the name and symbol of the ERC-721 collection */ constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {} + /** + * @inheritdoc IERC7578 + */ + function getProperties(uint256 tokenId) public view override returns (Properties memory properties) { + properties = _properties[tokenId]; + } + /** * @notice Initializes the ERC-7578 properties of the `tokenId` token + * + * WARNING: This method should only be called within a function that has appropriate access control + * It is recommended to restrict access to trusted Externally Owned Accounts (EOAs), + * authorized contracts, or implement a Role-Based Access Control (RBAC) mechanism + * Failure to properly secure this method could lead to unauthorized modification of token properties + * + * Emits a {PropertiesSet} event */ - function setProperties(uint256 tokenId, Properties calldata properties) public { + function _setProperties(uint256 tokenId, Properties calldata properties) internal { _properties[tokenId] = Properties({ tokenIssuer: properties.tokenIssuer, assetHolder: properties.assetHolder, @@ -174,16 +188,11 @@ contract ERC7578 is ERC721, IERC7578 { emit PropertiesSet(tokenId, _properties[tokenId]); } - /** - * @inheritdoc IERC7578 - */ - function getProperties(uint256 tokenId) public view override returns (Properties memory properties) { - properties = _properties[tokenId]; - } - /** * @notice Removes the properties of the `tokenId` token - * @param tokenId The ID of the token from which to remove the properties + * @param tokenId The unique identifier of the token whose properties are to be removed + * + * Emits a {PropertiesRemoved} event */ function _removeProperties(uint256 tokenId) internal { delete _properties[tokenId]; @@ -193,7 +202,7 @@ contract ERC7578 is ERC721, IERC7578 { /** * @notice Override of the {_update} function to remove the properties of the `tokenId` token or * to check if they are set before minting - * @param tokenId The ID of the token being minted or burned + * @param tokenId The unique identifier of the token being minted or burned */ function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { address from = _ownerOf(tokenId); @@ -210,7 +219,7 @@ contract ERC7578 is ERC721, IERC7578 { ## Security Considerations -To ensure the authenticity of a token's properties, the `setProperties()` method should only be called by a trusted externally owned account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the token. +To ensure the authenticity of a token's properties, the `_setProperties()` method should only be called inside a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the token. ## Copyright From 103eb5b18ffaa7a1cd9cf9da568ea696708e872b Mon Sep 17 00:00:00 2001 From: ruvaag Date: Fri, 13 Sep 2024 18:35:22 +0530 Subject: [PATCH 58/79] Update ERC-7726: errors are not enforced Merged by EIP-Bot. --- ERCS/erc-7726.md | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/ERCS/erc-7726.md b/ERCS/erc-7726.md index 85c4fec7c5..ee22070a36 100644 --- a/ERCS/erc-7726.md +++ b/ERCS/erc-7726.md @@ -46,10 +46,6 @@ Returns the value of `baseAmount` of `base` in `quote` terms. MUST round down towards 0. -MUST revert with `OracleUnsupportedPair` if not capable to provide data for the specified `base` and `quote` pair. - -MUST revert with `OracleUntrustedData` if not capable to provide data within a degree of confidence publicly specified. - MUST revert if the value of `baseAmount` of `base` in `quote` terms would overflow in a uint256. ```yaml @@ -80,34 +76,6 @@ For BTC, the address will be `0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB`. For assets without an address, but with an ISO 4217 code, the code will be used (e.g. `address(840)` for USD). -### Errors - -#### OracleUnsupportedPair - -```yaml -- name: OracleUnsupportedPair - type: error - - inputs: - - name: base - type: address - - name: quote - type: address -``` - -#### OracleUntrustedData - -```yaml -- name: OracleUntrustedData - type: error - - inputs: - - name: base - type: address - - name: quote - type: address -``` - ## Rationale The use of `getQuote` doesn't require the consumer to be aware of any decimal partitions that might have been defined From f89b9a080b0b070bed65bdb8d559c8e7115369b7 Mon Sep 17 00:00:00 2001 From: Riley Date: Sat, 14 Sep 2024 15:00:32 -0700 Subject: [PATCH 59/79] Update ERC-6909: Non-specification Nits Merged by EIP-Bot. --- ERCS/erc-6909.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-6909.md b/ERCS/erc-6909.md index 29a5011354..ea343004ee 100644 --- a/ERCS/erc-6909.md +++ b/ERCS/erc-6909.md @@ -536,7 +536,7 @@ The `totalSupply` for a token `id`. ### Granular Approvals -While the "operator model" from the ERC-1155 standard allows an account to set another account as an operator, giving full permissions to transfer any amount of any token id on behalf of the owner, this may not always be the desired permission scheme. The "allowance model" from [ERC-20](./eip-20.md) allows an account to set an explicit amount of the token that another account can spend on the owner's behalf. This standard requires both be implemented, with the only modification being to the "allowance model" where the token id must be specified as well. This allows an account to grant specific approvals to specific token ids, infinite approvals to specific token ids, or infinite approvals to all token ids. If an account is set as an operator, the allowance SHOULD NOT be decreased when tokens are transferred on behalf of the owner. +While the "operator model" from the ERC-1155 standard allows an account to set another account as an operator, giving full permissions to transfer any amount of any token id on behalf of the owner, this may not always be the desired permission scheme. The "allowance model" from [ERC-20](./eip-20.md) allows an account to set an explicit amount of the token that another account can spend on the owner's behalf. This standard requires both be implemented, with the only modification being to the "allowance model" where the token id must be specified as well. This allows an account to grant specific approvals to specific token ids, infinite approvals to specific token ids, or infinite approvals to all token ids. ### Removal of Batching @@ -544,7 +544,7 @@ While batching operations is useful, its place should not be in the standard its ### Removal of Required Callbacks -Callbacks MAY be used within a multi-token compliant contract, but it is not required. This allows for more gas efficient methods by reducing external calls and additional checks. +Requiring callbacks unnecessarily encumbers implementors that either have no particular use case for callbacks or prefer a bespoke callback mechanism. Minimization of such requirements saves contract size, gas efficiency and complexity. ### Removal of "Safe" Naming @@ -684,7 +684,7 @@ models. There are two security considerations in regards to delegating permissio The first consideration is consistent with all delegated permission models. Any account with an allowance may transfer the full allowance for any reason at any time until the allowance is revoked. Any account with operator permissions may transfer any amount of any token id on behalf of the owner until the operator permission is revoked. -The second consideration is unique to systems with both delegated permission models. In accordance with the `transferFrom` method, spenders with operator permission are not subject to allowance restrictions, spenders with infinite approvals SHOULD NOT have their allowance deducted on delegated transfers, but spenders with non-infinite approvals MUST have their balance deducted on delegated transfers. A spender with both operator permission and a non-infinite approval may introduce functional ambiguity. If the operator permission takes precedence, that is, the allowance is never deducted when a spender has operator permissions, there is no ambiguity. However, in the event the allowance takes precedence over the operator permissions, an additional branch may be necessary to ensure an allowance underflow does not occur. The following is an example of such an issue. +The second consideration is unique to systems with both delegated permission models. If an account has both operator permissions and an insufficient allowance for a given transfer, performing the allowance check before the operator check would result in a revert while performing the operator check before the allowance check would not. The specification intentionally leaves this unconstrained for cases where implementors may track allowances despite the operator status. Nonetheless, this is a notable consideration. ```solidity contract ERC6909OperatorPrecedence { From ddde12eee3698045a16202a41b25027186bdb10d Mon Sep 17 00:00:00 2001 From: Dongri Jin Date: Tue, 17 Sep 2024 23:08:30 +0900 Subject: [PATCH 60/79] Update ERC-7758: Move to Review Merged by EIP-Bot. --- ERCS/erc-7758.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7758.md b/ERCS/erc-7758.md index 1219feda4b..e4c7e75f14 100644 --- a/ERCS/erc-7758.md +++ b/ERCS/erc-7758.md @@ -4,7 +4,7 @@ title: Transfer With Authorization description: Transfer fungible assets via a signed authorization. author: Peter Jihoon Kim (@petejkim), Kevin Britz (@kbrizzle), David Knott (@DavidLKnott), Dongri Jin (@dongri) discussions-to: https://ethereum-magicians.org/t/erc-7758-transfer-with-authorization/20859 -status: Draft +status: Review type: Standards Track category: ERC created: 2020-09-28 From 4dcd0fc37b89ad553b3fc654f8f9d29d5003d549 Mon Sep 17 00:00:00 2001 From: Guillaume G <162377478+uni-guillaume@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:43:42 -0400 Subject: [PATCH 61/79] Add ERC: Tamperproof Web Immutable Transaction (TWIT) Merged by EIP-Bot. --- ERCS/erc-7754.md | 256 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 ERCS/erc-7754.md diff --git a/ERCS/erc-7754.md b/ERCS/erc-7754.md new file mode 100644 index 0000000000..2c8bb2dd8c --- /dev/null +++ b/ERCS/erc-7754.md @@ -0,0 +1,256 @@ +--- +eip: 7754 +title: Tamperproof Web Immutable Transaction (TWIT) +description: Provides a mechanism for dapps to use the extension wallets API in a tamperproof way +author: Erik Marks (@remarks), Guillaume Grosbois (@uni-guillaume) +discussions-to: https://ethereum-magicians.org/t/erc-7754-tamperproof-web-immutable-transaction-twit/20767 +status: Draft +type: Standards Track +category: ERC +created: 2024-07-29 +requires: 1193 +--- + +## Abstract + +Introduces a new RPC method to be implemented by wallets, `wallet_signedRequest`, that +enables dapps to interact with wallets in a tamperproof manner via "signed requests". The +dapp associates a public key with its DNS record and uses the corresponding private key to +sign payloads sent to the wallet via `wallet_signedRequest`. Wallets can then use use the +public key in the DNS record to validate the integrity of the payload. + +## Motivation + +This standard aims to enhance the end user's experience by granting them confidence that requests from their dapps have not been tampered with. +In essence, this is similar to how HTTPS is used in the web. + +Currently, the communication channel between dapps and wallets is vulnerable to man in the middle attacks. +Specifically, attackers can intercept RPC requests by injecting JavaScript code in the page, +via e.g. an XSS vulnerability or due to a malicious extension. +Once an RPC request is intercepted, it can be modified in a number of pernicious ways, including: + +- Editing the calldata in order to siphon funds or otherwise change the transaction outcome +- Modifying the parameters of an [EIP-712](./eip-712.md) request +- Obtaining a replayable signature from the wallet + +Even if the user realizes that requests from the dapp may be tampered with, they have little to no recourse to mitigate the problem. +Overall, the lack of a chain of trust between the dapp and the wallet hurts the ecosystem as a whole: + +- Users cannot simply trust otherwise honest dapps, and are at risk of losing funds +- Dapp maintainers are at risk of hurting their reputations if an attacker finds a viable MITM attack + +For these reasons, we recommend that wallets implement the `wallet_signedRequest` RPC method. +This method provides dapp developers with a way to explicitly ask the wallet to verify the +integrity of a payload. This is a significant improvement over the status quo, which forces +dapps to rely on implicit approaches such as argument bit packing. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +### Overview + +We propose to use the dapp's domain certificate of a root of trust to establish a trust chain as follow: + +1. The user's browser verifies the domain certificate and displays appropriate warnings if overtaken +2. The DNS record of the dapp hosts a TXT field pointing to a URL where a JSON manifest is hosted + - This file SHOULD be at a well known address such as `https://example.com/.well-known/twit.json` +3. The config file contains an array of objects of the form `{ id, alg, publicKey }` +4. For signed requests, the dapp first securely signs the payload with a private key, for example by submitting a request to its backend +5. The original payload, signature, and public key id are sent to the wallet via the `wallet_signedRequest` RPC method +6. The wallet verifies the signature before processing the request normally + +### Wallet integration + +#### Key discovery + +Attested public keys are necessary for the chain of trust to be established. +Since this is traditionally done via DNS certificates, we propose the addition of a DNS record containing the public keys. +This is similar to [RFC-6636](https://www.rfc-editor.org/rfc/rfc6376.html)'s DKIM, but the use of a manifest file provides more flexibility for future improvements, as well as support for multiple algorithm and key pairs. + +Similarly to standard [RFC-7519](https://www.rfc-editor.org/rfc/rfc7519.html)'s JWT practices, the wallet could eagerly cache dapp keys. +However, in the absence of a revocation mechanism, a compromised key could still be used until caches have expired. +To mitigate this, wallets SHOULD NOT cache dapp public keys for more than 2 hours. +This practice establishes a relatively short vulnerability window, and manageable overhead for both wallet and dapp maintainers. + +Example DNS record for `my-crypto-dapp.invalid`: + +```txt +... +TXT: TWIT=/.well-known/twit.json +``` + +Example TWIT manifest at `https://my-crypto-dapp.invalid.com/twit.json`: + +```json +{ + "publicKeys": [ + { "id": "1", "alg": "ECDSA", "publicKey": "0xaf34..." }, + { "id": "2", "alg": "RSA-PSS", "publicKey": "0x98ab..." } + ] +} +``` + +Dapps SHOULD only rely on algorithms available via [SubtleCrypto](https://www.w3.org/TR/2017/REC-WebCryptoAPI-20170126/), since they are present in every browser. + +#### Manifest schema + +We propose a simple and extensible schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "TWIT manifest", + "type": "object", + "properties": { + "publicKeys": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "alg": { "type": "string" }, + "publicKey": { "type": "string" } + } + } + } + } +} +``` + +#### RPC method + +The parameters of `wallet_signedRequest` are specified by this TypeScript interface: + +```typescript +type RequestPayload = { method: string; params: Params }; + +type SignedRequestParameters = [ + requestPayload: RequestPayload, + signature: `0x${string}`, + keyId: string, +]; +``` + +Here's a non-normative example of calling `wallet_signedRequest` using the [EIP-1193](./eip-1193.md) provider interface: + +```typescript +const keyId = '1'; +const requestPayload: RequestPayload = { + method: 'eth_sendTransaction', + params: [ + { + /* ... */ + }, + ], +}; +const signature: `0x${string}` = await getSignature(requestPayload, keyId); + +// Using the EIP-1193 provider interface +const result = await ethereum.request({ + method: 'wallet_signedRequest', + params: [requestPayload, signature, keyId], +}); +``` + +#### Signature verification + +1. Upon receiving an [EIP-1193](./eip-1193.md) call, the wallet MUST check of the existence of the TWIT manifest for the `sender.tab.url` domain + a. The wallet MUST verify that the manifest is hosted on the `sender.tab.url` domain + b. The wallet SHOULD find the DNS TXT record to find the manifest location + b. The wallet MAY first try the `/.well-known/twit.json` location +2. If TWIT is NOT configured for the `sender.tab.url` domain, then proceed as usual +3. If TWIT is configured and the `request` method is used, then the wallet SHOULD display a visible and actionable warning to the user + a. If the user opts to ignore the warning, then proceed as usual + b. If the user opts to cancel, then the wallet MUST cancel the call +4. If TWIT is configured and the `wallet_signedRequest` method is used with the parameters `requestPayload`, `signature` and `keyId` then: + a. The wallet MAY display a visible cue indicating that this interaction is signed + b. The wallet MUST verify that the keyId exists in the TWIT manifest and find the associated key record + c. From the key record, the wallet MUST use the `alg` field and the `publicKey` field to verify `requestPayload` integrity by calling `crypto.verify(alg, key, signature, requestPayload)` + d. If the signature is invalid, the wallet MUST display a visible and actionable warning to the user + i. If the user opts to ignore the warning, then proceed to call `request` with the argument `requestPayload` + ii. If the user opts to cancel, then the wallet MUST cancel the call + e. If the signature is valid, the wallet MUST call `request` with the argument `requestPayload` + +#### Example method implementation (wallet) + +```typescript +async function signedRequest( + requestPayload: RequestPayload, + signature: `0x${string}`, + keyId: string, +): Promise { + // 1. Get the domain of the sender.tab.url + const domain = getDappDomain(); + + // 2. Get the manifest for the current domain + // It's possible to use RFC 8484 for the actual DNS-over-HTTPS specification, see https://datatracker.ietf.org/doc/html/rfc8484. + // However, here we are doing it with DoHjs. + // This step is optional, and you could go directly to the well-known address first at `domain + '/.well-known/twit.json'` + const doh = require('dohjs'); + const resolver = new doh.DohResolver('https://1.1.1.1/dns-query'); + + let manifestPath = ''; + const dnsResp = await resolver.query(domain, 'TXT'); + for (record of dnsResp.answers) { + if (!record.data.startsWith('TWIT=')) continue; + + manifestPath = record.data.substring(5); // This should be domain + '/.well-known/twit.json' + break; + } + + // 3. Parse the manifest and get they key and algo based on `keyId` + const manifestReq = await fetch(manifestPath); + const manifest = await manifestReq.json(); + const keyData = manifest.publicKeys.filter((x) => x.id == keyId); + if (!keyData) { + throw new Error('Could not find the signing key'); + } + + const key = keyData.publicKey; + const alg = keyData.alg; + + // 4. Verify the signature + const valid = await crypto.verify(alg, key, signature, requestPayload); + if (!valid) { + throw new Error('The data was tampered with'); + } + return await processRequest(requestPayload); +} +``` + +### Wallet UX suggestion + +Similarly to the padlock icon for HTTPS, wallets should display a visible indication when TWIT is configured on a domain. This will improve the UX of the end user who will immediately be able to tell +that interactions between the dapp they are using and the wallet are secure, and this will encourage dapp developer to adopt TWIT, making the overall ecosystem more secure + +When dealing with insecure request, either because the dapp (or an attacker) uses `request` on a domain where TWIT is configured, or because the signature does not match, wallets should warn the user but +not block: an eloquently worded warning will increase the transparency enough that end user may opt to cancel the interaction or proceed with the unsafe call. + +## Rationale + +The proposed implementation does not modify any of the existing functionalities offered by [EIP-712](./eip-712.md) and [EIP-1193](./eip-1193.md). Its additive +nature makes it inherently backward compatible. Its core design is modeled after existing solutions to existing problems (such as DKIM). As a result the proposed specification will be non disruptive, easy to +implements for both wallets and dapps, with a predictable threat model. + +## Security Considerations + +### Replay prevention + +While signing the `requestArg` payload guarantees data integrity, it does not prevent replay attacks in itself: + +1. a signed payload can be replayed multiple times +2. a signed payload can be replayed across multiple chains + +_Effective_ time replay attacks as described in `1.` are generally prevented by the transaction nonce. +Cross chain replay can be prevented by leveraging the [EIP-712](./eip-712.md) `signTypedData` method. + +Replay attack would still be possible on any method that is not protected by either: this affects effectively all the "readonly" methods +which are of very limited value for an attacker. + +For these reason, we do not recommend a specific replay protection mechanism at this time. If/when the need arise, the extensibility of +the manifest will provide the necessary room to enforce a replay protection envelope (eg:JWT) for affected dapp. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 5a1ad45179a6a95cbcd7be67b904a5e5c679bb07 Mon Sep 17 00:00:00 2001 From: Andreas Freund Date: Tue, 17 Sep 2024 11:42:16 -0700 Subject: [PATCH 62/79] Update ERC-6735: Move to Review Merged by EIP-Bot. --- ERCS/erc-6735.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-6735.md b/ERCS/erc-6735.md index aa28a59a38..aed7c4f0b6 100644 --- a/ERCS/erc-6735.md +++ b/ERCS/erc-6735.md @@ -4,7 +4,7 @@ title: L2 Aliasing of EVM-based Addresses description: Identify and translate EVM-based addresses from different Layer 1, Layer 2, or Sidechains author: Kelvin Fichter (@smartcontracts), Andreas Freund (@Therecanbeonlyone1969) discussions-to: https://ethereum-magicians.org/t/l2-aliasing-of-evm-based-addresses-from-the-eea-oasis-community-projects-l2-standards-working-group/13093 -status: Draft +status: Review type: Standards Track category: ERC created: 2022-03-20 From 5be18673add4a866c3ff70440fea747b1eff9c7e Mon Sep 17 00:00:00 2001 From: dRadiant <103012174+dRadiant@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:39:15 -0400 Subject: [PATCH 63/79] Update ERC-5173: Update ERC-5173 Merged by EIP-Bot. --- ERCS/erc-5173.md | 14 +++++++------- assets/erc-5173/nFR_distribution_formula.jpg | Bin 0 -> 21956 bytes assets/erc-5173/nFR_distribution_formula.png | Bin 12607 -> 0 bytes 3 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 assets/erc-5173/nFR_distribution_formula.jpg delete mode 100644 assets/erc-5173/nFR_distribution_formula.png diff --git a/ERCS/erc-5173.md b/ERCS/erc-5173.md index 61eb9e4547..0eb2fcfe42 100644 --- a/ERCS/erc-5173.md +++ b/ERCS/erc-5173.md @@ -317,14 +317,14 @@ Any realized profits (P) when an NFT is sold are distributed among the buyers/ow We define a sliding window mechanism to decide which previous owners will be involved in the profit distribution. Let's imagine the owners as a queue starting from the first hand owner to the current owner. The profit distribution window starts from the previous owner immediately to the current owner and extends towards the first owner, and the size of the windows is fixed. Only previous owners located inside the window will join the profit distribution. -![Future Rewards calculation formula](../assets/eip-5173/nFR_distribution_formula.png?raw=true) +![Future Rewards calculation formula](../assets/eip-5173/nFR_distribution_formula.jpg?raw=true) In this equation: - P is the total profit, the difference between the selling price minus the buying price; -- r is buyer reward ratio of the total P; -- g is the common ratio of successive in the geometric sequence; -- n is the actual number of owners eligible and participating in the future rewards sharing. To calculate n, we have n = min(m, w), where m is the current number of owners for a token, and w is the window size of the profit distribution sliding window algorithm +- _R_ is buyer reward ratio of the total P; +- _g_ is the common ratio of successive in the geometric sequence; +- _n_ is the actual number of owners eligible and participating in the future rewards sharing. To calculate _n_, we have _n_ = min(_m_, _w_), where _m_ is the current number of owners for a token, and _w_ is the window size of the profit distribution sliding window algorithm #### Converting into Code @@ -334,7 +334,7 @@ pragma solidity ^0.8.0; //... /* Assumes usage of a Fixed Point Arithmetic library (prb-math) for both int256 and uint256, and OpenZeppelin Math utils for Math.min. */ -function _calculateFR(uint256 P, uint256 r, uint256 g, uint256 m, uint256 w) pure internal virtual returns(uint256[] memory) { +function _calculateFR(uint256 p, uint256 r, uint256 g, uint256 m, uint256 w) pure internal virtual returns(uint256[] memory) { uint256 n = Math.min(m, w); uint256[] memory FR = new uint256[](n); @@ -344,11 +344,11 @@ function _calculateFR(uint256 P, uint256 r, uint256 g, uint256 m, uint256 w) pur if (successiveRatio != 1e18) { int256 v1 = 1e18 - int256(g).powu(n); int256 v2 = int256(g).powu(i - 1); - int256 v3 = int256(P).mul(int256(r)); + int256 v3 = int256(p).mul(int256(r)); int256 v4 = v3.mul(1e18 - int256(g)); pi = uint256(v4 * v2 / v1); } else { - pi = P.mul(r).div(n); + pi = p.mul(r).div(n); } FR[i - 1] = pi; diff --git a/assets/erc-5173/nFR_distribution_formula.jpg b/assets/erc-5173/nFR_distribution_formula.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3b2b373a759fa3ea33706a8cf197e2b72dcae3fb GIT binary patch literal 21956 zcmeIa1ymi&)-Ku$cNXsM8r*|B!QB!F?j9_-yAwiy;O-iN1b24`?j9fz2zpocKIiQH z{(JT>W4t%+8{_WkUe&YboK;=*b$8jEy`C1H)&a1*w45{m0)YTo$Ob%Zf)?Z?Bwneg zDND<}kb(#R05kwV0t_1f*x9=}tI3Fy>*(r{!>HgR$Mo%**iMC-@g@4C}0 z|5oEaXCj)KxtKsy&LBT(XUN4NWx|Hg*cQLj^uOrWztcj$Xm?jfSBQ?vFWOl{O#(uj zLTGx6KhdxMM4LD||I&|!=m^=_y8XJ=ukfpOC}#GW>X0J>Ic8kwZkpka9UdHVeQOFayW|Ilvw;0azgv2fzlf13XV(0SN#G z8v54`0}TTU0|N_(1P=!ZsE9}iNa(0wFghwa8U_|VHU=ghCK@^pF%BL90TB@q7@LHQ zgpdrMkcjYCCLkDCSU6ZX6nJH;tjpm|^cXb>d;g#m)b06p~pL=d>4 zpnpAY{|c~h&@k{ID2NdI|H1!F;b{p#frcajLxUlA>f8FiQvFT*jlkas{NINF&M+At z>lFFx0A{=A9nb^LW>wVyC}^4!&JlpaVgmrF#JIR>jVPOO(fFjUI8WM$~vM)GXiY%2<9t5Ojnr2w;_uFReQ>fl_zDnSoSxKBm?(WILwOP*z=a|Efa4iI_ zt$;c7gJk4weY9<%6_iY+6z=1S1|st>KjmqYL>rBPOL8j41x!`3>~1b^-$F#UZ*RSz zDynsC1na5F7$@OHHA4!d8;H)nR_`Rdiec3|=gdcW0yqzXw!RtU7z$G;I8x*uzg<2Q zg>?QDJbUlD1=Vt2YOG*oOTJYZi=l`m&QNuLpNoDjbV%^pY-sjfx@+}c)W^j)VRS4W zmFzu;G#=yN&(Y$TOg@a4=)a9lAHwB6>E>k}xPC+$wJErDDjRLW5KC;@;h&eD{mQ^u zt1F9t6dv$?xY9*`wZF6FlsQbG+2=GN$+1pS(|o>OdPv6MeNLfU_)n4OZF2&?DVwZI zW_W@9H9>fRsr~k3Jc+ZN#an64HzB?SWO$JzXQi{JF2NdKzR#Jh@zdIHJ&=LHua+RzygE z{5M@BpFAU=Lf1{nWOid$^f%UjI|9kIAjnlu+*T~hD>td`3G6Tbv&{ePEdHbzk`55B z<-54#L!&=CT$XKEDM`)MR!)62_-HcuNo=BO=Fb05+W!L*`om?cy{o^`?usbW50Ly) zL!{qIy}G^VpRz!a)+$>3xLcG~-_8{Q_i`6bSZLsi0w?U;z*u1~wQIhX;#X)W{K+ja`L;yMv0FlS>*hJw|{`nnAEo zPe5dzgW2cvV$SGSVdYJ`JMCCmVHm6P?|=clu)!8n?izfHxM3*KG;vWj3?rxeHB3Re zvHL-shWVl}3cKKhyWQ?pQlV#00A+_yK;YTs8WoSf&Vg>3@jI1dHMwGe!i&$V(yzOg#BGRbpVebgweiU}c1Qi5g|PSf){IkHWoB*GEfGgv zTR#V`;T8LKUtSsv5)SQMQ&yzqS^7w2+sWPkOo#)If~9Bym-OuHDAT3VZLE1- zV9(%R*O3@v__4QkVH_{IF=Wb6x7qnXl3V?0UmB3F6I;(Jt8yR})| z`>*nwBMl{yow?0SU2N0~r^%)t5E#fZ)6o`xNIi&!FS^%_p+A;&bVc<1goE*zlB_B` zqupeoFoO4dcD&TWxUKia6i57H4;BilO8Q21?n(1hq3>1jY)vhW<+HJaxnMU0Jzca4 zlV!eynlj&+Z_C%mxz|3#Pr%7zNA-1BaMDZXW6iN%ga1#WxzAP#nxs6=AB8yjNJ26r z3SKE=c%g$^W9K%rp$G=34skO|rEp*!nc6t{^`AG;7?4vN(j+UKS2+lGj2E8vJvZ$!kf`L@uq&?eaz(Hub%)cTR%podF6aBgg? zTo204yE!%CLv8F^C*Q_9sP0uVQSlDFTSqF4=0swPW;DzMSZHyR0ORerc!h9+vz&90 z49rfnv%rA73fK7van2q&W<-H6t^gcUsAB}xL4;8-TMvDY{l=7GMYJRKEA3VTiEx>C zU|k$AA3drJ#t4KLXXZ`BrsEGbUF9eyCbK1x*^n@em*G!vBJ#-=jLsM+sI}~Q$8TF> zpvOLA@^Q?|+RtdgyL+GCGB59KVY4g@V$TSd)i~q2*t{<+IwLOB{>CsX_W zPHiEcz`ajJyH;Ux?s6keJZx=nVX@7@(B4!3zLE6o7Fk|IlRS?ey>GFtDo#_$pUfX$ zNb6N3S{MDC`l!28CXvz2+aO^w@-rBp*H6H~3lImJW^wBi066<_S$~fIG5cvT9N<9P zCM$BeybfquyjbhjlFT@1S3vjhC8V*8GQQC9?(Rrf-ssoynvz>4<_$3wO_hotxT*W0 zw4%Mtek2m|TN^VpF>EOBr|H|uqac59c%i9@RxQJ&4eJu8sXjB)0e8<}{0$vy+%XJK z@$kD@Nd`V_U-Gdv&yCq2+*cf<@(6mqg%!P~TSW!6Tl_K3pEP{^ep1aguS_8qzin2c z3fIA6UkodD#)Tzh{1TuOdOa=bW?q1&mC@zI4ic&vPF;d#>Jpaq_>L+MI`=_cNLc!$ z^7Y2y=1l}*S-;T;!xLa(2SpPkO5qsnpG`N*<1TvBWefj)5ve9v@(Ez+u7`D{LODB6 zZJo?Ls+4$m2x}Fh!);yF<{aAfG#F=kzvCiQX^}E=(HuD0@PNuMXikr~Q__yt9g^;t zQg))WbVZH0HXo+t{^O7Ew-g9oD%b5#s_?G(%?`X6Lj1I-FJ65Ljny@^51r`a0`MI~gU3#mV zxv2qx)~MuwV(c}uHj`B;Lx5?bvH3BkaUG#xTCvf<{LoT+M?(Xq=t6^FB)_iWL1A(E zWp$3&Qhpoae0f17i?tFbcFJWKqJWH?iJn`dgtjWmuDq9C1@fzkkx1Rt8cq|l4e}=+vFy4my z1Wx23N*CV!(Aux1Y>YoIasTSbJAUh{AxqyPASn3%L<8zy8cLAC00|MAcq9CggNZPH{`PCR3}ZJLh+7 zoSowa2Itmx{bQs6CjuEMq^L$1E1t}JYY7ol_H*+q7;R6^NW=r&(Ptj})CXiJ9{Tg^ zE=XqFwdHR;*GX|Imo!qmHTFh3+ZxB0B4=TuD1VfUXDs3KBn8DTJ!66q8%dI*RxBYl zlRYB!j8mC|bGiw;(4~xYIVA8@85hnxDGL^uA(IgrpRb7fq4pO2eZv#b<0p`5D{R#N zm{64Jbbqe!yq;7ge2wvog0dU(ryavS&a&FV6yr&gAv_1&JLQ%1T4j zRA@mFj(ng}z^0Oa#@K41B431dxcCHYOmFOlKj*jTb9Z9Ri!`>QEqtZxiE}-@(z(B^ z7eq~l!n@hSMl*sOn!{&uvYo#X7|zWnglMJeVDoq)aA&lV|xl+lS^r8aj=x+2gH&~o-fM8_^hjQq9> zT-08Cho@yFw^N*Pewxg~_!k|#x1R@|fL?uNq+o3&Q4{#8T;&I0q){ZCPoK1=h%N<3 z5m+cMEP^Iev5uHrZRs4;Inck5;H_Eci`)ymrH^93l14SVekk&Gn<|O!U+HhGVy!%*Ye~`-b;fo>lG~2Z(|ORM z3jYqD+=;!gQvu3OpqC={$G`nv^Ejj&aKK2CH$L^!^_vyf)=97xik;HO?p`1P|yDP5nvV5E4!pPa}6|77YXIMG3rYN1h zd?6`n+>%`G;&1OXT&m!voXX#j2D7ajh;Hi0-EZjCCmVN8d{>ty*h!%juFdHy1@|-8 zO6MUF??I1z%7R&yBQ#|p+HPT6<~ZVIA1tC<(Hi&rzT@+3x75)-d6@p0E~?pu4l8|FXU?G6$(!dm*Xi7;RM3ZL{dWw)@E0-bjlm-J0XH#Q z`r@yeMDGn_>Ld$^3Yn^eq+#_JK<`p?BaVBO?ax6-eU*vOJBrM^RuyUm(D6l-YD3bVX&u+Fr69ttXtDFBhSMAdO+@@rom{PiF9KV zJg58uij0{AzuJc$)ch-rM0$Afy(zx@mP87)vkcIpm{9EL7L`CwluFfcTfyVY_iqyq z*P!{+S;#LH9w|QS@$;3T5M~ziotOwQt`gkH^@bl0jw>i+C&dbAQ_sY>VK>fGK3_(p z+@dPKdjfD+hNP)iqT}_kpHVf4YibOqu5-=^DpG9`CKIcV3R=d%$(8T~>E-H`ZZq)~ z%BU89gJ3^YVmcp8?kleW!u-<`TxQG7syIr`VYHTnv?xttw?-JLdY{f2R(~N6+^f z(WgYcKI`I1*oozZ@iE_z?+HM1ud~~hcd9B*Pe-6VOVkCQ!fBa7L=k-DL+kJjg0_)wso^hK>{5}s*;w)2&7JKn#@wQ`SHF4L#%*`SbK<8AiT5WhUlZEBhY`x5(o+fX?a zp|Zd*ec-Vli}IvFEn&rokIVH|c9ZejaayT|#>hp1`PT0s8RGz()1;cICNFlQ(Ntn* zt+|A(Hh0Xpk@3Zp?8DINwtdF0{8<9o1Gm-dREd+iikz@t80-R+lLO4G6 z>q`bV)chTn87tjnTxE?Ps&cBP5;NVD^|GZ03o=NP`IbA;j#cpyR8N4Lll~}jYah2s ztN>yt{uW(UO271bRYPxl^J+eH&KCo<&rDF}itRRIS~P(?+_W*j=Pt3gvGfnJGxWKY zImzGQ+G5wba0;nXj%d(+n@SsxX%bdH^}HIuxhU-0ry>dAbW>XMF-5jKB!#8>1mW%IDR zC*;jPbN9@W(IL;!hWc%qcl#3{`1=J>6j_#Q!at}n26Rm5l6kCUMti1CoIxEbPPz62zc4PEB#nG# zwC_hvU+06l72+*Dezw%^XK`aUNpep*Y+8ZuFzzybdY{(sL^u$ZW}J?WO{KG~Ozd5E z8<4uxg_o-PiR8INWkn9cU`sRu3g2FKEBHg$z$K{PP)L7}V)io6maXc5Rb&5w6LA;+~89nxy~B-A4$r_7>sI%N@TGIFO&Nl;n6$g;@E*2NwPVt&5~ zFLjd4tIEu?wrbDWUze#|+ZcMXEmlGkZ9>)RTkzZaBy2u+pLOH|six%fdZmG;a8jKN<4@kCHC1IoW29*K-Tn6QbYm~HJ;zvjKi+6 zP7N2@2K}MLV!k0BtBlXVFAi~eUZXvQSh_7Z=s*~cTGtGb?31{gvb zdem`tF*Q<*J%O6N*8nEwDb0%#Yna%1Gj$3?gH2q4Yq2R=NDBFOEaIi5}^v;s?haGkOh?2|7 zqSmlanRi^lILWI>46extW$GCY-$P52berN#bE*kV12FsN!3^7yi3V zg8SEB-WOZ^P|wGbVWKO?>7;B}9*VEBX@o^IMi{iQE7QBGbADI>RuqZJuUbN~&jbd- zk{AZQBcN!vYJJsmcPwBpsrz~b{rmlKl|y)0-lu$Cl^N6}GW$vpKG?6c{S7+86QKF_ zm=xo&^yh*Q)r02uY7d#)vOS}-xGU|k&JD7|yf3cyqYQCdk2y*l25?MwGLMk%Qs8m&35XRL%f%h7B%zY9o=x~xMs{wsi|Z0XESKM& z_L?sM_t5)i)BBcYE78NLZQsM@re>FCiOXE_d*$f8935PqT=?!JkYx{I&8@H5u}nHz ztR$xA`=3^CwX{$R)JyVDgb%ZH&I`v#h((0vCOqaPRkB0gdsx(KEwxGMoNV?;$ZqV% zatwEI98kVc7{=M{O?>TzZ{rYrC_Bn}2?v!OBpYEhmNvQu4Sp%NsLa#xK_G|Ry1362_!1Z)KuX(qUum+lV#eMy*5A;h*e@AbtyiZ>u zjc0br6t=|aU81*>MzWTYf0`)U4k<`#2ODN$cH8kcC4?cuYf2GM5oBt>xm=cB=$u`IOK54taI7Z?L;NNde*G|oiR9$oO&}v*E;$Gxuw-0)wwAG)T;`Y=^l6?C@S5-HVMbt^I=@p(_yk1pw zafIgbmomp3XJzFpmsoWeXhYm$1>cy)UF{5fV`+!ri!$cI(f& z_nRN{SetbUdMTZ-xuz8Je1@_?5kc_#ZQAm9mRCv`_w(F(!xwbMgO>*zYY+epA!|k~ zV2G^;8VU{s@$dZIR}zE)P_T=sf{mRLI?n>gb86Ti79y3&jgIqwnubIuo`9iTW(5T( zn}NAJ8EiC_uN6-~(bN&G%M*~$dn?{bcP>_4TeoAQl@3QN91=a%5gK=Q^loqK-g!)OFG5x%Qw` zq-a)ITYisABVhg}GO7U+>i8i8^$9@kty>VBZ5CJkv1uN~!MK%{|C;nF){UAte4BTt z(<(DIC(fK!VhJ_{qCH;w_PjT;O9*Ss@^zdKLIa!epuNuIekKVz{WWnw?GB2pdgAJDo>tb77cI0{KdHvNNX z*=(tb&!()>+bmqdKF8(|*L~4R!(>l)Ul=%puX0p5aZ{}1LNA)N6sWb5Q zZ&IgM>%r6LaeE&Yc^A6#C+e33_`iNcput8%+mJytLV(H&H`6+zjgr^}P(o>EbD=4} zV!TdLG_`tDpOUy|d!Pa%1gheFlccH@fj8W(9M~lnmJ~@B751JGCJ7W*3zg z+7Rv5?qa^@h=r zv%%mdY}<1jM+PU{4H>EN9W_zT9g_wXqp%f-VVb$>vdYTbY}=(=kVT{3$|$v{(lF3D z;|YLSLmdj;^ZM`XyEv$0SAX7_7_{%|2xyx_T#)`ldbQJ`$#hH*P;Br1ANE@q7zWcM zj5fQmE=q|q^}cwN@Q8xGmDu!*GBtswY-!(WyN;WH9J-dAZRy?eF(MaFD!^jMkp@Hr) z#+B`l#GvK>6lM_QQxHBR}GN z37@M$U~(1f_57&N1F;3U4QgTb)Vcy2c81CTLR=j-gBWyzA@0Zwc1FYGqRwu#L8JlP z+GUJ*1Xm&oKgUful=#u)7j%b@>mR=2%hOaDoxkkdYzyl3hL8M#j&n@Pv>>Ei?eYIQ z8w$(}m*RJX5Y^YbffEGn7T3V;&a)fx9W<1q)H#vkjD6QYKHAq9a4z+dkr#vMy=&{tVOzuOl}?^P1li75-Xikop=+KApO241Y`H}FS! z_Cq7gdojrNXF}=<87j)J_cB zKZ;ucF@3eWpy4LCN>B3R32=asa8%gOSi0SEl19nLBJIIdV!=YE!?yY=(G)9e)NL;Gi}Rj z`{Xl?m~5b(RdJy_Q{n+E4PQ#^dpLSai zXLtFUZm23fmwH7$F8Zo>QnAouTjRm|qI&+;!Z*Q4``)AI3DBxIofs|+J?ZwrwX(=y z8A`_>Qpu7Zq87LDcBj|gt5DoyPdR)7gq>_OOIr)GWX2nqGly^qs~=asknXK{?Hrt? zswj6}BG5))ymE(?+$Tg!!D6@LlXRrY!Qq4Wh49jp-lio2qWWg z5Oedq)~7@Gk_BUKfc?3L9vm*^nF_)&OOx!BzhiFK`YisJTA~?Q{;Gt6cB|zPlc3ih zN}bw+u8^gLMY@>H!xQln9;Bf3eUM>3<;~>r3P7RLm-mqYA-qqk^hFCb)Wz|QzU6qOuoX%}riXq7!MJbvnZJ{NE6{z$OCYzh0j?*S zJ+;kgAoZ|*!y*o*ZcegqG%Ur8%^vWJOhVsrN3*{)a=(aUCG*(H%-q{e_aHnSXgrWQ z8~dS@tLV%*R}M)&sT;Vw+G==+1h2#M;%@e^P8ZpOn3m;F>gLkn0+tM`Rfgv;TQ>chJB*ON5U9ex5sAciXI?{kv?3->Wi#V{B?Mv|rtcZX7^=`+ z@SXvdsxFZ8xdwHeZ@^W;ZXBN^Oxg^9nlD{-`9vwTl{UI!x*@rosrTgUo2$2MMVb@l zu_DZ%n$r|t)Y-`K&r>=Gav8qZfgbWXbXp6f7y{#Kl$%${7w|08Vg2x;6CWa(NgTA# z$*qiV9jp32nbTyqfKBZUhSD3;+mj7sSp(GIbU>Vy+Fl%}x@>9}MVUIj*7$JF^m2od z2rvCrzd>qJ?X(#epBqc(>VH}2mS4`!Ec^s?UbjaKPk`K98>I6{;5Xj*4a-boeJrFp zikp_$#uPo!V=3l4sTs;1h4;55>$hDJH-7IIWT zfr>*plR#kuf!RO^7#+X_(r?*_f#apf|BDR${~;HJ<^zlJLA@ZJfCocIfOBQI5@Wgk zDg28(f`Bd2zYzTe8{C2Ndvgf|fV2NX=dajMaOD1fCHpV=2mk=fXCnGv>iv}hxa-dn z5DK^p;n(-I0l#sf0a4LEi~lzo2IUVH44)c0LbWssmIN_5Gy*0dR5OHP^oRIAP}t-E z`F~*j-sAW~zCwohEJNz`7eVFkj_EIu`J4SW0)Hd$Hv<2s5cp4AQhzzEg8xgW)!#Lk zz!1X(+iV55Fq&hlzqb;FonGA*bd{rK9r?0|odAD9z0c5vQ!F){CPkld&`l z3ILg5tCd!P?u5FS)}ULyKT^#-GB2Y0SDlAD`8V(&7?N5LFky+|g);kOJ^-44^CqQi zXk7TVH786{uiTYj!zI*Gl172RH{$3p;uBdoc8Ayg(CgQ-Mle)d=U^n z6g>OBuk@I@F@3u}!rA+tc6NDa@=L8NcNG=heorI+m~g0l&8jbNH#1SnRa_Tvl&a)n zj*H%R#JoFcAK8Mq-;yTamk?lNQkrcm<`3ja;bmj3O=_%OY+S>U;$DTq7Mw4&l{I*3 z4w(2Z$daHpH&>M`nce%65uxU;7?^(z3m^|cr1CE$@_?6;!%J2SWh^h*MyhhkJ2f9b zsrLAkn0==%^V->2DkI1!(=3-~zj{aY>^Zdf7@J&Typk07O-`kgw54b~FZbZ*SUoBM zC_uZIb-_J4`yER#a1d?bA~OHw8XQILT_LomBZ1ZaWqqX zI8kWvSZ$UF{D{|w6UX%49Qo2SI0D!#B#2j&i~cy&XKDZ@XE-Q-i(ftT$_&c$duZdJ zSl3jTJ>x$56fgnvJbEi52YLG#An6Z)c(?CPq@gLUga}>};+OXn8Hqkm5j#IQc$m*W ziL}v;Ktw8lyG5$~KH`qlxn+6FS+|r^wL{SX)n`m>U;5J;8(?NKhz{yfBYCW@_HWl( zGgX!*bXdqm6rE_!qelvKIMFl!6ZBFJn_?0P83{y(U<~1NB8-HELOE*cV zpt;T;9=CAR8sFXyT6~3h)fr|BfX;kdQ&pp3iTaJQz7l8RJhuU_l;jFt<^w97f%Y}Y zTTuIQfGBhjH*U0a8woIA6SFyIx|2dfFPKcvk+umFD2fIJ;$eEzO!!if@e>?jU8<(@ znG9uYiuCihtS;wCO!Ye?WlgLMCWN5$Xqimd0QML2t0+Wikv~amlE12frA{o9C8haE znSE8^8eq8S+WIbRH^ra^5z2!<EFxbII7_@4$(?RxZofH z;BAHOy)Z)h=3O)k(W&RacP{B7N!LaDd}c9uNk9QuVzFKv+m-cds^%>ojbX`m(`I8G=aS`)u?iVycy)?nZXiHk%__ z`tD+n+W!2yv0%<%1ejTQ4I=xRNlz*AT9pK@PA7}=4}fSRLyjaI+v{~%s(MY{&Q*Tu z@}7NUl6tD+jXic$0CbPvC(IgblH058?`c%XNR5I|;h2m4jW7k%w$(UlycW8Ex#lb) zLYyFwF=SaSd%$ojr-^aWN(-^6Y#-vndjAB7D`dwI2$gF7g!qa)-2G!M_1_=163JEI z{Dn+vxXmJ{!ITUN7hcp!N7yHyvFGzVvXo7H;3YvuP+c3;Ue*Tg*;Cr0l|lxp!Wu|Eu5N=^Z6BuHUyOF(!fzINo`MVk47d5x%}y)bMK>w0J)1~5y` zZQ6waSZ0{)D8ONhwqb-n0p%1JhB3BNi!T&!sH`nf675$$U!tHSSf6FH$xpfm@M2%U zE*$}Nx|qpkHGZ!f-nZL>d!wl`F;zjuP`^S>J#2q>wP2 znd@A4IufUeM->~eELh7XVLhRzJkT(Sc55zm|eY~$5HGsJgF<)La$c|>K2ur z3hc2xFsO1#h=j3)!>k)3xt{1o`)se^Xc@LwLKO$~CDAi2<3tb!{YQejptAdkSCUGB z5z@&Ru{YgaZ2oBex7>XsLC{c!E!Q0Yg6OI|oN2Rdw0WeYY%yDFT`K-CH|hf@9!I)u zAUxvuR!J)()Or>`+BO-$tv0|!b_HDa6D}MyEKkosPF@#F-(L%YS3p!5@&`jN zpo_tXQ|fsP4*Om_8-vWu3DKuG4scYYP_SU(#jdoN3msy776m(^5M+sy~}`2EF2#?&)L%+@xI<;t>O`qPB8yu^QxL%U1d=t zKwZp0NJ&hz9$PD&e$|Ji@Gc&el6^US+Xmm;h^tQ^Rlwj0IIXQIUTEAVcaM}bD4ANY z5-o9Hy5q@X)V4_iKhIPmTS7F2Itwt53>AQeqFYyBw*Y((9y&I<730-%Lq3x1y&<&D zqZfUR7dya)?ei%|==0WA{UzvauNhW6!$X!lwh6HV2W>bCEOznrq#OTI=Djm=z7-wv z9XspW9+Pa!P9`~8t{piaXM97%x>VxjDA9Z1*jGBzqzB#<%$QArlharrJq>XXN;TiAI`QeMdQ6=XFe|=I7YvKMygUik^Se1vIdC~c5Z`1rMM4S8+GuJcpB@XnjjMwuX`|K1nf}R>4?g4lAguJ$y-_b3dR7wpGp7qJR!szcM$VHh)fDj9EGI zqUw1{Y>-wLBLel+0iiJR?2j%K#iIyvuzw&BSz6vEH8JfSOJ^Qta-;NPV>b$;0y(do z!#bC(7k1$XX#yf#&=5K4Q7|L-*;jcY@osy-SCy8?upVUS79JhaRf1m{N709>9mUHa z`q?dvZ5Pg}GzG_1b!&2|K!pSuc34rn(vU;MVn4(Is%-+%S8_Nve```LK!=d;0iH!_ zhbI$(<{EnI%u*#sJOl|FYhkZ_KH+ns?02`Hmrx+mB+3m|N&E4L`DI5V&)8Me&)l+UF zs1P;M2>Igstb%mlM1ZK&cM92{7@(uHK{6}A$S;HuXIEK=dKN9)#w*NYws7TEGPEa0 z&wQxSe(siF{pPt!tPB)mSvKk>pB#lK>ViLffMExD;n+v@9&mA&aIXKUS8gtq>8a>f~|>vXF_vy>9J@pPPvG@AEF&kp6tfsbzZo) z_Wf{@mP*@aM%ksCDt|06nY2I6f3hBLj?-kBK0iiiOC>I-3uGx{PEQ$u%r8Z4jP%m5 z>O}`~pm>m2HIA9qi5m}slMT|LD8EPBo>HATIjaDVE8mBix#zuV>&2RcfrOX-KM@04 z<%6+jurfFRN*b)Kc^QAapdv>Q@Ph;MTor*Gtm(gJ!>JK`gKhh$V=O#jWGvkUR#AkW z)F(i8W9x(qR(S~xPsFJ8L5hZjP)yGbpmbtT%1g#kSTG0X(!zb8x$9nE(l+w9tsxIruI&JOl&8l@0&-*~FU=hckr6n?QOSZKM?kyyp=q+92T#aYrVBgExQsvufQI!BN2KDK zMl%?|xPX&p7olq5yl($}IIJk%#~f&Rm&?GMXAl#v8X_qh02fr%ja6)* zp>lvB+1b&B_=?(U-in*H8Zqr49|X__T^iI$=G6n5z6c%l^|Rw%_SEK8 cSJHd>$rmUQiOWz3_LJ~>yib60%hTfj0#h|SA^-pY literal 0 HcmV?d00001 diff --git a/assets/erc-5173/nFR_distribution_formula.png b/assets/erc-5173/nFR_distribution_formula.png deleted file mode 100644 index b4f42acd4aad6213b3be4470c088098bf64e62be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12607 zcmeHuWn5HU^e!S2(%lTrATfYJx0E0uHGss>NOuq2C5_ZAHet$>09(9wH$jVav%re}#mE8~|JwqN4(T zQ{OKEH<0c*zLJqZDjT3$1HLGmK;=wdzC?NiT%#i)-y=Y}e=7p~B86BWq1;^~Au$7= zNJ#fH@BQ~Q6Z!8`)a1*A#lMn!|Z*N2BY41dwEQRTzFO_K}Z5>Q#pK)?=a?y)C zq@|@5axgX(c=cTRpXR_fVR~~XCp!TM#MRZ6)Acc@t%Dhao1dQ_!o>sO;o$%zI2_$= zoM3JoHjWH`I{Dkra}!4+2MaqV3tJo7+kRn&w$4t%^z^ri{{8u5r;~;0f0}F@{}~oA zK*;SA2sbAeKKJ<$gm%^dwxKh>$plTRifelIirduloh-uaS>U z&3ZOFwYH*Y@aFm-=W5QgBL#};Ta{HzLG<@9WW|sP-uj|2A`(!p2Vad%zL5Xt2JJlz zM&w5UE-3$rbfBoACV$>5twUi1p5C@pCjW%{w+C83Cgx0@&mB>=KbZb`{MNTO)BC^v z*tzc|wldjx6?6WpR}FRR{+<5Y76xG$g;<>Si#pE#>dfRZ2i=@BP9Fsv|7$HH;(w;#|KSw)S>T=S_}u7R9+mr0v#mAXTbrhwi-(& z4>T>2j)~UqA&Q>ce9*##Sw<?FfNa4 zn>nIIuTKR?D=a6#ClH^rzU%>w$GtVcjxbjq z-)*=QF25VW`9p;=R1~uO`hx+%2o9YZB9PCeef@JVp~-~jPGf{ojBw2}p<2p-Sr!?cX7{&Uvyy?8iZLgEGo@qz;k15E&tHLUlW)=rERVGn(OZT}x zi_UHUY?2ed{Hg?hMdjGf{Qxq9$@!T!=xl2CT0{OpVGgp9-Us)UcVY5iYIld5^YP~J z;_@beJ@@5A%{P4u-J;j_d&BY&V#~1-*5g^9n*}t{Q*phhFB#=JwPmMQJ3g~2oaalt zvtA?BR`uI;mNGxf{2EyAcE2i9CJ&!_L)A+mBJp5?3aZ5A>my#wb*8&ev2*p$z5 zVP9C%-LhNuN97SIS)qq<;)9-@lun|-)SggvD$2jS4!$i^bkjuWY%!3iva2|M zLao7kmzIf?{dqxiyswSC6>X3FP-yt0hjB_Wi2lpvJgyJ;7yM%DQscsFYqI)LfHg(> zt+z=b^h|0WgYIzVhZ)BG z7>_RJTEs|`Oj;psi2-VkgQp7W_K;2B4omz3sry@qNlxU4c%Old!x1H=L554P%y9m6 z_}zBw5B4RLUC9kp63}6H1ooePcoZe?@!=1Tv*qM?Vy;?W7`cSYtoKQ}R2%)zR}0~f z2lyDU@2%XkKkr`e`feh+K`r@dNs1zYcw-q@zxO3N`aW0A>Bime(EZ(`_EktAOgFe) zt{_7yemBsB>@qiAG5j}mH=JZJ+E=y7peJ2`+v{enAcLe>vz${=Xs@HpT9T4y$p0B& z`5fum$iNc0cYdBh!T!n?X&J`yarl#SY73V0uCY>`_;R+@Y1KP_Y0!&en&bGs?-Pc> z(HrN)GL77x`Xl-sL^RC(p`{`3hH6KI5tO98t{Y!|iFSi%@GBd;Ep&}u5!yl@Vp*rZa87QyuKBiO97!uhMHfctrAP?&%}Z{cZ`loA8=d z8j=Qwj2s#$T8=k{rn;=)I#IV!bI}@^;+;1SX2=|zOGw<(VghNTPOm4gMg`^N?J~(@ zia0b6YUel1izd-mD8^DNVJh`)JOpY0ZgWw&_E962c$d z7t_Gmbh?n8mswhfmekg;iISi?H)KgD|?F{lAXc+9DT3%Ml!CS&|nMkuuoSqlBg54I2eMT zfXl%k^l)o+@x9V2gzRI7^^XNEMDcWUNz0!We-)B0?ixYKe(_G*Ny;26)LCdz3U0g8 z-Myv}GC+Xbo3xS&tF@g?-=_B3ZDmXE#3tg)EqcnakQf7{tw7I4cMw`H%z32an4%(3 zl!xilI<{-1b2dk1N%vxac5M}xA8b>;3jPt`MeNzhF^daoP#$%^?teU(Yk)>&C&qs& zJHEJkvD=QTn$FHlE#Uz!hCU{~b6QXv&MY{e*RO@&DlrM*0YVPhuE zYyayOd4A(Cu9OvYIjf|{03(u4DY(gKXjAXZA%j}#?V!j7J2l!B=4_YvJoAxPjPS9n zC9Sl_=7M-58g}ce8*ys^4EP=c1A7Y9yS)g+ZuOr$DdJ@dY@ySpSnRVMsV>H7SYim`Ix!@W{FMnm<^GIWhW9zn z1OZ8Bc-Fqd*+;bAZ$8%t84E))pqD?+zuCg$qi4?sTs0Ja%i=O$?vzvwytsawVEv;= z-QqX(tn7d%hDosJL^c#h6a#Lh8CuRl=wq0Y;kaMUqoB_jKYo|fC_|9zxz0Z8NmV{+ zCon)yr29EG3}zz|PH6QSW9yad-=<~;5w*cz7$>e`nc;4jg$xIjYeVvkz8@4aB)u#N zogval?^HGqT;($-v7>Prb@aObuH&GK(w1na`3C-K+Z;sHnrhqhW!0E+U1F;1t$X<; z+TO=~q2c@(YPUH*i(zH(55zwnq!k0JmLMu?LpC#SF7N0UYH5yUcjaKEf}J6CL!E4i zY+z$9Aun(0~_*c^ENZNX^K6y;K#tw^zUN z-g4M#>k^(oipegySPB`6Wp9X8Ok}7EC4V?zhEIqqsuEn$E&yfXXjfxFvh@^*J33VVe?9=u)$^P=;Tcn>F;@%bPO8_dlCw=*gaD#BIG;#E{W-t zzqXMR2~{7oct%HF`f;IKBy||;T_2A{)5}t}<`V61zba&`R5t{|JYe5^CmJ4LQYP{C zO1wj8*Cdo2E3z%`2N9blHD^v#2lB-7`n* z6Ir{YO_0XoSWMvLIECnf4auej36&*{NK>*t{7iOYE_KSoqF@J!6ZUv#?N{1~p6F~5bCz^Mi+%>AZs?J)Y|D^ELs=yd8cX&S2C#1n zdRpgssyM01f`jE$HWcHrpk?buDo=;CL|%oyq%B!YJ@s523K$1tseo*4O~Fi`cdowH z!F8L+zFp3ir1aMSC$J1u-J)ISn{53!_fEmmp!4;+b>i}M@7`w$?y|h+jLTUf5nyf9 zf}%I6p8DK(fY3T}Oh{)FDAOahS^o5ETS4il!sCw-7WIz0&Zu}^CFo(8KI&bTjFhWla? zJb?t~<-pC^mCfoX%j$Oyg=w977wgu^yeg8{blUI$Nw#~b&#YfOp7-`_(kp{BO8+QCT;%cC!^m zGW9q4slwM;c2&PPE~-~Arc@P^8YrYsr+2@AF-!1>X7Gr{V2SOa^|CUFtx|6|`X1fG zV5hoQg57X=3oDk;QrH58Bx74v*%^=hyY}%(&@PL#+cohSwJvPFEGHQ*c13NGvQ`=C zv?p7@+>xbU>)Ao~7asIpxdrE`y8$qf`&2Su2eJ0@k=GKa_vI(yD{OM(dnWT&l@3%I%ct|)3N(jR zK<2^9+Mk6kt-F@0zLf5{EmutTTsM@EM0e~BwRBIFkZJ~X5h7URXjGM2t`kRtnm5(0 zBGhOq=}SD42u^9!#1Gfti|eljLlx5eG)2I6-$o7hQ=Mj5CQw4aE)!qGCZw7SEK-x?0x^sisMs^Ecmhj zZt6Du1=bsKt0M%neDP!6FCJqrkuk-6VIPy)y;{fMJpkZ{AFFPE6|eKay~}F<=W)yi z*|UL@qiAYJLsZN1i9L|_A-)`ApMe1DRq=a8R&7tn)}tmpXKLpB*HHg`*s+6f$QK;_ zRzwpvp(_O}XY1gZ$I%bXc;`~9w7!GcCU4KW{tL<^;d8qQg4a)Dew($1Vv!wpK1yGW zPi7D;D1BQgMJUfs(htj<;^HRp9BzA<5z*ekk3D!tV;F#uxf?o^$EaPWW0QEovYryO z#cVfSY;VZMCv&zZChK`vTwHIIH>VFABzp+;>z8$yfCWx$7nWm`44achEwEp(>_;$M zcpWVCZx9alb_?JTwug64&4b$06DUC~j{q-22 z|1KeLLF4!vB?~U|Q@WXR=P$1>-6U}M=6sKH>>^rtU7@VFgsLQ7BINrJd9UcclT?>2 ztA+gP!lT$00=$-2zVWV5taa$Ja*JJq=*4E$R5)QT`D5P+6UMgZXA?OTU-jS4Z^kSH z5%@2&vNOVhB))u2`^C^$I}5KbP=Cv%J`#4gAlsCMj-wqPWd}}Gzjo+k+NW^p7%yfI zI7i!Ps}6o3NMy$RvV{$0Y$j!&N(#?JWXA{0(j!Hxn-G1ukt}^JG#utY2npoL%yl8$ zKJm~ve#|5y`s5hE@=J~s%Nzxi@YL4CN-j&%3G3RKS81>ywQmfj7t%hR^pxJBJL9ZF zoHr75o`C#_Dqm1_MYu`D2S#@ppQWnc!QV{DuZNpR2l=G=`z#LYqdkr>RqM^#qr)hh z;3#cog_|)d&2ifF7z)8+r)EDI2Wy*lHBWE$+&i1gQ=Ja@4Rvc|Lk{qUTUW!4P8qtY z_y}y@g47b7=o|SK^re1{GMtb`td0o9>7RzHi1xNR>qWz_7}8Z-)@giNd3t}9ax9Qr z;ALEf4f5|D@ZipL&wG{%h!XsdsDmEj3OKN zyXrjD4`_wfhLq$e6)*8Ko*bM@pY_R{zedanL8Y{M=Zp2?dDo&CVo{xQBS+&shsqXn zg^NF*W7TLYT0FZ~!VG=g+obia%(==kQpG|}(=HIF!@5h@A<>3MK@w>*>_MLAHk01j_-O6wJ&b4hCOW&h;8&B0(v+gtu+9}TL!_$%j z9MAc#y@pn^6`;>`UX1^|ih0I4$j+Gz`~K9r2b2-^8obfgQ}Rji;2q69xJ9+Vw8YiJ zcQjE031>&-&31wrqbK3|3!hjX-(+8o`suIs4s`hG|GHwQbkNpA_EPNH0(l)HpixH7 z@1Ij#X~*t_*>h-L4VU*lo{XzoAxM%gvF$ZRHz$8hRz2g7Bk8Lje|m@r-6~Qq4h|C- zM_f{LFZfkGv-F;~?8+{w->j6c6g#|lAUy6r$mK|8u$ERW^(I*TNijFNLbeaWhB~R) z-k8ARunz>PH95uFz0ypwEN^@^Q`AR4yS&e_P~AI6U-RCi>^ZGQ&tO^`o74w~%#@?B z`%YN+o$TMqn$7^`E6wzZ`?;(eV{lyl>xLj%IJurb<`CXfj-}66M$@MT?|@k~uRP1JzT~g2PMcinYfIbj_7+!@hzak~~v2ss!fPs4)v=6XjlFzc*>Y z+pS@yk0uE5mwGbG1>$bqWe*2dO02t*DVtsJ*#oQ^;NQj3sz=Pw6Taf_nRLImDZ%a{ zz~vJNIYLmk65awqY?ir`Urv-z6T3REm)@=DnRcD$>H*;c3N0|NQ=8_iqjBh=V*|MrJVP;rX?vkaLZwm7 z%xjqbAQ~~`1A1jalehB-gada#sHg`2YMy&9Ye9d6s`Y_XmYAZzTJB_016)?n zx~O59_FB2-rwhh%g!4zT?9O$njq_!=XBu~bV`skseCf6G5A{w>eQ)(!I?zJ$;+CYm z*s7g%;(4lmhr{2BJwUEjL!AhDdnM>N|Dec;papm9`eFx??y>%H08Ni6DB>%5PgfM> z)br2X@YpIfR22m+&fqH%5P-D}feph6<-ZAINr!T~=jtlo?G#{DAJZc+>nFc~%U?`z zZGNq@#KP{blW0(wm<-WMUbMki`-q2$hpxyD?RPQRe3dnt+_KjV$}q+3p7d84_CA^6 z<)Bk-0u2hkxW(|kD5m0>E+PT2Zx~W<QJa+0PEvgZZ2!tY1MKH( zFi_jiSUTpHfo&yMGB>&&+^h|Nh7~@;Twwd` zey|dK^dK20k~ry(%hARwoZ;erF?Y6_G5f2mSOG(nKS8qOQM?+W_l&*msm91t%P}Xc zj}VD3$rX{8z8J;4A_1FxagZmCkqRYMcZ)n4AXb{tx=Y$&IBdJ8@8aOL6e|-a2^Z$V z;go_3poOppzjA_hC>4ukjDN26GS zVZ&q2hlb$XO-u#t10v>$j*e9Kr1pltRVb(sa)^aUwC^o7O_n6Km6SxT=65pdBZ~d43&Ac~|E02;hz2o;qI`srujstR2X1{oLJ*m@sgxkj%uARvKeTQF{`Gl-tGe z7F+i6k?!92f1Khyj3>b@ZL9%UAv~}9lsO3%q0LcG(ItPzko3_F0+otA!&^2hX7@;^ z)<)M;GydviR&>T}Zx#WTrU3gFq`7Eo_r(Y)Uy{M4?@75!>`^@V$~0Vb5$o+qP9W1p z(JLI7#@%-Q&gN9%uSm#$~Tw33dg)0h?!d?aOr=j^^5LR&+DV(@Hj;o^Urr zAa|EcO-}|HhDhN{RW?MR38u|4$kHg7!q5fTW1&O4_>pwWMayNDdea%z!e51JgoQr@0!GShVu>V)_=%n;q#;hf(eGF+w_?39C0xDW z$Biewjstgn*swyoJ7SfWk0OR&xY*zGM^9kfo z`cMb=jndj?Q-9iCb{^LF;^e++5AwshQ4A3om2CE zlZqa+vSdv9H4m^Q;nSH+js_SqL;~0TtoCPpC-KZPm0aYZX{w=pv0fFUub9(W{{%cB z9%r-+vj$uRvlqnF!}%M|*NZ+MS?iq*OPK(aiZwGMy5NxgP z$Zfr_*Y=&nTQUm0FcRLiinlK8`7=0kVRt?VFjJKd;RMvjz?^p3?D6eOvCu~$7y?{cnlyLhA3t^Jl1qvf%y|cJJ-9Xi$jyv9=i0g6WpFT15qh(v;KT*gRMVbNOL?|oWKH3kRhn(hs zuFOjwE`WNpgHm~I6|dop!5{--7?i?(#g16}uk%w#2Wojs?>H60=OI12+l6s#{{1M? zbVenC{dhEt3Ouk_TdBWW(YY`Nz~ z)IbYA@)R5hb{7KW;#HPlZ%{q@JKg;ufGV%gN>9eCEywc@n}GVGrs4^JO z%AGd99?e^hD>91h8WZZrVJhe`0_%lBz2OHyKyx)nA&zbM!@C2lbO$>73=Sh9gJw?P z?jWTZS{#LXXSS@tM+`(UZYAKsU9V!*N%`3E23>IoJKtA6HPijcDaj92Jq7};th(?* zD8nInxpaO_^@9yD%^7 zJFjW{f&97(%=zNSm(_H^h>}V77Sv?2lKf(g(l@i^9{cklpnTnEWy6W&bn3TIr<({! z6L=dCeev}m&)p7w_Q4{9?gICj)%T?M*z4TrOX9WVeC(4rv#zjf`{U->3#<& za0zXHUaT{jJ&0^W%WS!96NFr;g)UG?`a<}#&e?K5 zXcAyA>e(Am+}(F2u)^%@zu_-OlQPQla4%+Xv1E8TwD$3mmQ^T!aOh=Sdp2*_sHk_j z`RH&V0+RnZ*L^;Sl*H$JB;ysiGJ%9!SL8L~O$CG>b|IILdev{n3Qo^*i;9EvYJ(S- zPp#Uur0Vj-b-0b)CQOpm&~t_b=+zRhmKrOwQk1mdTmq z*)Dk-1H+3y90V-k$&=$p^wI$7S)$wbSuOufzy`(nwLWOb#MYan;iYf*pRfihS>7e1 zFn%{j24ez5nXdgp7>mm&Asf2Czbx7HExUN=zbF()%Gjni4|V>TzXwp5>}2Wv`p>!5 zI`Nnu5+o7mUH9mDZY7SLc9gGu32?y4VxM`|8+cWdwLIG%y1SWKXsxR z%)1e=vi#NG>BFnwqG5TJVhW!GJ20#4X}S8#`^8&}F{0^26hwLEAw_!y1X ze)E+@)MVXB>!YI#DKd_Ls!S^yz#|Of8GtduwBi~JRMLC>^Gs*zoVTU|jaF$&n7JEB zr=C{ko1s6%TC<+0%q#r~W1SC*3XJQrqq??h2vi|E>kApZg-XV{K!$v&BJH^RWWPTK z9EpVwsZ-W3@z}*MZ6CGB@IIEa?(Bb)kT|_As2~uJML9O|+Y|cB5S(%C8#k^*rk9U9 zT-!?!K80}4d^^nRD8)5g)+T&@q3b&HV|xeR=es}+{=lLEK)<6seq)RdSLg8Goc`j7 zA8tX;^qmiI>zVH2t`h28*m(J)+V$*q4a^v=y^DO7=2!NG*XA>8|8xmWqjR+ zY9^m!fvS@)F~-0=>XD3}p*?+C`GoW$L$ zq8hcqsvn-+2cZDmpvnt|b7w{<6E0s4bfM-g=GC)liv5e3fyEHTU1o*;YtH14I+rSw zwK@VXn+te;`jVKU5x~=M7#?Z0f9EMdDI)A4=G60Y3vKQy+2>r~tH%;_G-Epe}|El*E*It8;0rJ@@&OD*) z03+ZkxG_5Hs5HchM2R}wvbZ;$flRVQxgljYR!5%9#kglXGXO_hg<`>IucfjR6Ccx% z6UNU!=X-yDifw>ApP8CH1suHW)QjKd5tdz1*cSNk^9srLU1};dmdQZ!5@%8((Q{eZ z!;p4dQ6ZZnp_LuN^@s;wrmpwem+;F7jUR64UDfGip{I@qff!*wwn=_@=HP$l;iIV4 z?hMC;^eHdpA8HdjNCbsJwst?hSFU7c@Czdl(~|hI*hw6HYV4aqJ8aDto6L4?Nykn3 z4udYY9q(~CD4h9PpAKxtcV%RaA+OIKJhgFQ0CUXh*Nx&@BC2(p9pG&dc~lCc`~c(; ztlUUM^;51STN&(=JB9KDaeYEdTC%}nfY+M%OJteJrM&%(yVstjUoSPAtp~-Z&{zb8 zWvac}DRR%1E%g~14DCihUTu%BnI`)jx=xcxlrw_5UiJ}sS3NxNhvD13bH9GoF1l1k?#(s#0;2C@lt9FwO?vA~j!^LqjyJ1gq zHkXLq6E@!JtD5rJMGoFGiL6|L6?p%ue3f4l!6U_ASKa;z$XE}nv1&XfvgP@P48u}Z z$}8_*hXJ>WN^~b@d;Kt5IwuPE>_?uKevj4Ud&^uWWEYaR^> zYip~vU+i*OpElw)KMkzL<1}e~p9F~^7<^}+TJAay!DhDZ(k^6{iwwCl7{4&vhU`8Y6ly*fZ9iIe3&Q zO7E%EkTLUnZ(b>scti-%{ z7Ls*^A5aGkteLhVu1k)WJ4hCqFq)OnrJnGD84V8HJ2;*_d^upucQS zy$rR~nB~R#=8WA3IG&0ymN@^|H%Xb;#ct=CDHoduni`pN^5b=KYkqdH1jku z7`f-Y>8S&kns5Y@LRu2VlznN z364B_@RXyKK6Lmiw|lLc?k;5|j9LLUH7jSW2WKom_qRoog?)<^CTa;Kxc}hZe`$mL@X{_Q4veWW0wt zq^N4B?&$(W56c6+-=3yAIs*TJkWeRN972c(=0L^eDYhPPu&!imlJkLNH&75a@f7}e zeE%<7Mo`Ffk0YSkDyb7pq=Pb_lY%MP)kyN?k(0KYkwLrqdi)XzBJdLOnz zS`}ubegzHkp<^@4`iH%cmjEVHj>2R3hp{xbU^*(5=}!;;ZDybb*q9UdIQ`$Tnj-<~QJ-Y1|91d62RM54KU4Jo(-iIAAeGvsD?EF3 Sd4Buv2y#-2&&wnX{Qnm-RqvPp From 33003678d3efb46030da469cccb81fa5c3c522ca Mon Sep 17 00:00:00 2001 From: djdabs <87738563+djdabs@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:32:44 -0700 Subject: [PATCH 64/79] Update ERC-5791: update to v2 Merged by EIP-Bot. --- ERCS/erc-5791.md | 166 ++++++++++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 65 deletions(-) diff --git a/ERCS/erc-5791.md b/ERCS/erc-5791.md index 34e06f58fb..14d38362c2 100644 --- a/ERCS/erc-5791.md +++ b/ERCS/erc-5791.md @@ -2,7 +2,7 @@ eip: 5791 title: Physical Backed Tokens description: Minimal interface for linking ownership of ERC-721 NFTs to a physical chip -author: 2pmflow (@2pmflow), locationtba (@locationtba), Cameron Robertson (@ccamrobertson), cygaar (@cygaar), Brian Weick (@bweick) +author: 2pmflow (@2pmflow), locationtba (@locationtba), Cameron Robertson (@ccamrobertson), cygaar (@cygaar), Brian Weick (@bweick), vectorized (@vectorized), djdabs (@djdabs) discussions-to: https://ethereum-magicians.org/t/physical-backed-tokens/11350 status: Draft type: Standards Track @@ -29,12 +29,12 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL ### Requirements -This approach requires that the physical item must have a chip attached to it that fulfills the following requirements: +This approach requires that the physical item must have a chip attached to it that should be secure and signal authenticity: -- The chip can securely generate and store an ECDSA secp256k1 asymmetric key pair; +- The chip can securely generate and store an asymmetric key pair; - The chip can sign messages using the private key of the previously-generated asymmetric key pair; - The chip exposes the public key; and -- The private key cannot be extracted +- The private key cannot be extracted or duplicated by design The approach also requires that the contract uses an account-bound implementation of [ERC-721](./eip-721.md) (where all [ERC-721](./eip-721.md) functions that transfer must throw, e.g. the "read only NFT registry" implementation referenced in [ERC-721](./eip-721.md)). This ensures that ownership of the physical item is required to initiate transfers and manage ownership of the NFT, through a new function introduced in this interface described below. @@ -42,9 +42,9 @@ The approach also requires that the contract uses an account-bound implementatio Each NFT is conceptually linked to a physical chip. -When the NFT is minted, it must also emit an event that includes the corresponding chip address (20-byte address derived from the chip's public key). This lets downstream indexers know which chip addresses are mapped to which tokens for the NFT collection. The NFT cannot be minted without its token id being linked to a specific chip. +When the chipId is paired to a tokenId, an event will be emitted. This lets downstream indexers know which chip addresses are mapped to which tokens for the NFT collection. The NFT cannot be minted without its token id being linked to a specific chip. -The interface includes a function called `transferTokenWithChip` that transfers the NFT to the function caller if a valid signature signed by the chip is passed in. A valid signature must follow the schemes set forth in [ERC-191](./eip-191.md) and [EIP-2](./eip-2.md) (s-value restrictions), where the data to sign consists of the target recipient address (the function caller) and a recent blockhash (the level of recency is up to the implementation). +The interface includes a function called `transferToken` that transfers the NFT to the function caller if a valid signature signed by the chip is passed in. A valid signature must follow the schemes set forth in [ERC-191](./eip-191.md) and [EIP-2](./eip-2.md) (s-value restrictions), where the data to sign consists of the target recipient address (the function caller), the chip address, a block timestamp, and any extra params used for additional custom logic in the implementation. The interface also includes other functions that let anyone validate whether the chip in the physical item is backing an existing NFT in the collection. @@ -53,73 +53,80 @@ The interface also includes other functions that let anyone validate whether the ```solidity interface IERC5791 { - /// @notice Returns the token id for a given chip address. - /// @dev Throws if there is no existing token for the chip in the collection. - /// @param chipAddress The address for the chip embedded in the physical item (computed from the chip's public key). - /// @return The token id for the passed in chip address. - function tokenIdFor(address chipAddress) external view returns (uint256); - - /// @notice Returns true if the chip for the specified token id is the signer of the signature of the payload. - /// @dev Throws if tokenId does not exist in the collection. - /// @param tokenId The token id. - /// @param payload Arbitrary data that is signed by the chip to produce the signature param. - /// @param signature Chip's signature of the passed-in payload. - /// @return Whether the signature of the payload was signed by the chip linked to the token id. - function isChipSignatureForToken(uint256 tokenId, bytes calldata payload, bytes calldata signature) + /// @dev Returns the ERC-721 `tokenId` for a given chip address. + /// Reverts if `chipId` has not been paired to a `tokenId`. + /// For minimalism, this will NOT revert if the `tokenId` does not exist. + /// If there is a need to check for token existence, external contracts can + /// call `ERC721.ownerOf(uint256 tokenId)` and check if it passes or reverts. + /// @param chipId The address for the chip embedded in the physical item + /// (computed from the chip's public key). + function tokenIdFor(address chipId) external view returns (uint256 tokenId); + + /// @dev Returns true if `signature` is signed by the chip assigned to `tokenId`, else false. + /// Reverts if `tokenId` has not been paired to a chip. + /// For minimalism, this will NOT revert if the `tokenId` does not exist. + /// If there is a need to check for token existence, external contracts can + /// call `ERC721.ownerOf(uint256 tokenId)` and check if it passes or reverts. + /// @param tokenId ERC-721 `tokenId`. + /// @param data Arbitrary bytes string that is signed by the chip to produce `signature`. + /// @param signature EIP-191 signature by the chip to check. + function isChipSignatureForToken(uint256 tokenId, bytes calldata data, bytes calldata signature) external view returns (bool); - /// @notice Transfers the token into the message sender's wallet. - /// @param signatureFromChip An EIP-191 signature of (msgSender, blockhash), where blockhash is the block hash for blockNumberUsedInSig. - /// @param blockNumberUsedInSig The block number linked to the blockhash signed in signatureFromChip. Should be a recent block number. - /// @param useSafeTransferFrom Whether EIP-721's safeTransferFrom should be used in the implementation, instead of transferFrom. - /// - /// @dev The implementation should check that block number be reasonably recent to avoid replay attacks of stale signatures. - /// The implementation should also verify that the address signed in the signature matches msgSender. - /// If the address recovered from the signature matches a chip address that's bound to an existing token, the token should be transferred to msgSender. - /// If there is no existing token linked to the chip, the function should error. - function transferTokenWithChip( - bytes calldata signatureFromChip, - uint256 blockNumberUsedInSig, - bool useSafeTransferFrom - ) external; - - /// @notice Calls transferTokenWithChip as defined above, with useSafeTransferFrom set to false. - function transferTokenWithChip(bytes calldata signatureFromChip, uint256 blockNumberUsedInSig) external; - - /// @notice Emitted when a token is minted - event PBTMint(uint256 indexed tokenId, address indexed chipAddress); - - /// @notice Emitted when a token is mapped to a different chip. - /// Chip replacements may be useful in certain scenarios (e.g. chip defect). - event PBTChipRemapping(uint256 indexed tokenId, address indexed oldChipAddress, address indexed newChipAddress); + /// @dev Transfers the token into the address. + /// Returns the `tokenId` transferred. + /// @param to The recipient. Dynamic to allow easier transfers to vaults. + /// @param chipId Chip ID (address) of chip being transferred. + /// @param chipSignature EIP-191 signature by the chip to authorize the transfer. + /// @param signatureTimestamp Timestamp used in `chipSignature`. + /// @param useSafeTransferFrom Whether ERC-721's `safeTransferFrom` should be used, + /// instead of `transferFrom`. + /// @param extras Additional data that can be used for additional logic/context + /// when the PBT is transferred. + function transferToken( + address to, + address chipId, + bytes calldata chipSignature, + uint256 signatureTimestamp, + bool useSafeTransferFrom, + bytes calldata extras + ) external returns (uint256 tokenId); + + /// @dev Emitted when `chipId` is paired to `tokenId`. + /// `tokenId` may not necessarily exist during assignment. + /// Indexers can combine this event with the {ERC721.Transfer} event to + /// infer which tokens exists and are paired with a chip ID. + event ChipSet(uint256 indexed tokenId, address indexed chipId); } ``` To aid recognition that an [ERC-721](./eip-721.md) token implements physical binding via this EIP: upon calling [ERC-165](./eip-165.md)’s `function supportsInterface(bytes4 interfaceID) external view returns (bool)` with `interfaceID=0x4901df9f`, a contract implementing this EIP must return true. -The mint interface is up to the implementation. The minted NFT's owner should be the owner of the physical chip (this authentication could be implemented using the signature scheme defined for `transferTokenWithChip`). +The mint interface is up to the implementation. The minted NFT's owner should be the owner of the physical chip (this authentication could be implemented using the signature scheme defined for `transferToken`). ## Rationale This solution's intent is to be the simplest possible path towards linking physical items to digital NFTs without a centralized authority. -The interface includes a `transferTokenWithChip` function that's opinionated with respect to the signature scheme, in order to enable a downstream aggregator-like product that supports transfers of any NFTs that implement this EIP in the future. +The interface includes a `transferToken` function that's opinionated with respect to the signature scheme, in order to enable a downstream aggregator-like product that supports transfers of any NFTs that implement this EIP in the future. + +The chip address is included in `transferToken` to allow signature verification by a smart contract. This ensures that chips in physically backed tokens are not strictly tied to implementing secp256k1 signatures, but instead may use a variety of signature schemes such as P256 or BabyJubJub. ### Out of Scope The following are some peripheral problems that are intentionally not within the scope of this EIP: -- trusting that a specific NFT collection's chip addresses actually map to physical chips embedded in items, instead of arbitrary EOAs -- ensuring that the chip does not deterioriate or get damaged +- trusting that a specific NFT collection's chip addresses actually map to physical chips embedded in items, instead of arbitrary EOAs that purport to be chips +- ensuring that the chip does not deteriorate or get damaged - ensuring that the chip stays attached to the physical item - etc. Work is being done on these challenges in parallel. -Mapping token ids to chip addresses is also out of scope. This can be done in multiple ways, e.g. by having the contract owner preset this mapping pre-mint, or by having a `(tokenId, chipAddress)` tuple passed into a mint function that's pre-signed by an address trusted by the contract, or by doing a lookup in a trusted registry, or by assigning token ids at mint time first come first served, etc. +Mapping token ids to chip addresses is also out of scope. This can be done in multiple ways, e.g. by having the contract owner preset this mapping pre-mint, or by having a `(tokenId, chipId)` tuple passed into a mint function that's pre-signed by an address trusted by the contract, or by doing a lookup in a trusted registry, or by assigning token ids at mint time first come first served, etc. Additionally, it's possible for the owner of the physical item to transfer the NFT to a wallet owned by somebody else (by sending a chip signature to that other person for use). We still consider the NFT physical backed, as ownership management is tied to the physical item. This can be interpreted as the item's owner temporarily lending the item to somebody else, since (1) the item's owner must be involved for this to happen as the one signing with the chip, and (2) the item's owner can reclaim ownership of the NFT at any time. @@ -129,34 +136,63 @@ This proposal is backward compatible with [ERC-721](./eip-721.md) on an API leve ## Reference Implementation -The following is a snippet on how to recover a chip address from a signature. +The following is a snippet on how to validate a chip signature in a transfer event. ```solidity import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; -function getChipAddressFromChipSignature( - bytes calldata signatureFromChip, - uint256 blockNumberUsedInSig -) internal returns (TokenData memory) { - if (block.number <= blockNumberUsedInSig) { - revert InvalidBlockNumber(); - } - unchecked { - if (block.number - blockNumberUsedInSig > getMaxBlockhashValidWindow()) { - revert BlockNumberTooOld(); +/// @dev Transfers the `tokenId` assigned to `chipId` to `to`. +function transferToken( + address to, + address chipId, + bytes memory chipSignature, + uint256 signatureTimestamp, + bool useSafeTransfer, + bytes memory extras +) public virtual returns (uint256 tokenId) { + tokenId = tokenIdFor(chipId); + _validateSigAndUpdateNonce(to, chipId, chipSignature, signatureTimestamp, extras); + if (useSafeTransfer) { + _safeTransfer(ownerOf(tokenId), to, tokenId, ""); + } else { + _transfer(ownerOf(tokenId), to, tokenId); + } +} + +/// @dev Validates the `chipSignature` and update the nonce for the future signature of `chipId`. +function _validateSigAndUpdateNonce( + address to, + address chipId, + bytes memory chipSignature, + uint256 signatureTimestamp, + bytes memory extras +) internal virtual { + bytes32 hash = _getSignatureHash(signatureTimestamp, chipId, to, extras); + if (!SignatureCheckerLib.isValidSignatureNow(chipId, hash, chipSignature)) { + revert InvalidSignature(); } - } - bytes32 blockHash = blockhash(blockNumberUsedInSig); - bytes32 signedHash = keccak256(abi.encodePacked(_msgSender(), blockHash)) - .toEthSignedMessageHash(); - address chipAddr = signedHash.recover(signatureFromChip); + chipNonce[chipId] = bytes32(uint256(hash) ^ uint256(blockhash(block.number - 1))); +} + +/// @dev Returns the digest to be signed by the `chipId`. +function _getSignatureHash(uint256 signatureTimestamp, address chipId, address to, bytes memory extras) + internal + virtual + returns (bytes32) +{ + if (signatureTimestamp > block.timestamp) revert SignatureTimestampInFuture(); + if (signatureTimestamp + maxDurationWindow < block.timestamp) revert SignatureTimestampTooOld(); + bytes32 hash = keccak256( + abi.encode(address(this), block.chainid, chipNonce[chipId], to, signatureTimestamp, keccak256(extras)) + ); + return ECDSA.toEthSignedMessageHash(hash); } ``` ## Security Considerations -The [ERC-191](./eip-191.md) signature passed to `transferTokenWithChip` requires the function caller's address in its signed data so that the signature cannot be used in a replay attack. It also requires a recent blockhash so that a malicious chip owner cannot pre-generate signatures to use after a short time window (e.g. after the owner of the physical item changes). +The [ERC-191](./eip-191.md) signature passed to `transferToken` requires the function caller's address in its signed data so that the signature cannot be used in a replay attack. It also requires a recent block timestamp so that a malicious chip owner cannot pre-generate signatures to use after a short time window (e.g. after the owner of the physical item changes). It's recommended to use a non-deterministic `chipNonce` when generating signatures. Additionally, the level of trust that one has for whether the token is physically-backed is dependent on the security of the physical chip, which is out of scope for this EIP as mentioned above. From 9689c5ac08dc54df3b6529a59ffb1693ff2dff66 Mon Sep 17 00:00:00 2001 From: Lanyin Z <106770708+lanyinzly@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:12:23 -0400 Subject: [PATCH 65/79] Update ERC-7527: Update erc-7527.md Merged by EIP-Bot. --- ERCS/erc-7527.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ERCS/erc-7527.md b/ERCS/erc-7527.md index 042dcbce31..0f53f4d4ef 100644 --- a/ERCS/erc-7527.md +++ b/ERCS/erc-7527.md @@ -143,6 +143,14 @@ interface IERC7527Agency { */ function getStrategy() external view returns (address app, Asset memory asset, bytes memory attributeData); + /** + * @dev Returns the premium and fee of wrapping. + * @param data The data to encode to calculate the premium and fee of wrapping. + * @return premium The premium of wrapping. + * @return fee The fee of wrapping. + */ + function getWrapOracle(bytes memory data) external view returns (uint256 premium, uint256 fee); + /** * @dev Returns the premium and fee of unwrapping. * @param data The data to encode to calculate the premium and fee of unwrapping. @@ -152,12 +160,10 @@ interface IERC7527Agency { function getUnwrapOracle(bytes memory data) external view returns (uint256 premium, uint256 fee); /** - * @dev Returns the premium and fee of wrapping. - * @param data The data to encode to calculate the premium and fee of wrapping. - * @return premium The premium of wrapping. - * @return fee The fee of wrapping. + * @dev OPTIONAL - This method can be used to improve usability and clarity of Agency, but interfaces and other contracts MUST NOT expect these values to be present. + * @return the description of the agency, such as how `getWrapOracle()` and `getUnwrapOracle()` are calculated. */ - function getWrapOracle(bytes memory data) external view returns (uint256 premium, uint256 fee); + function description() public view returns (string); } ``` @@ -216,6 +222,8 @@ Token ID can be specified in `data` parameter of `mint` function. ### Factory Interface +OPTIONAL - This interface can be used to deploy App and Agency, but interfaces and other contracts MUST NOT expect this interface to be present. + If a factory is needed to deploy bounded App and Agency, the factory SHALL implement the following interface: ``` From cf8bff877b00d56cec0c60007a25bae0937d0d03 Mon Sep 17 00:00:00 2001 From: Archil Date: Wed, 25 Sep 2024 18:09:05 +0400 Subject: [PATCH 66/79] Update erc-4626.md (#581) a minimal implementation broken link fixed: https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol --- ERCS/erc-4626.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-4626.md b/ERCS/erc-4626.md index c28df5cba1..41de5ab9c0 100644 --- a/ERCS/erc-4626.md +++ b/ERCS/erc-4626.md @@ -576,7 +576,7 @@ For production implementations of Vaults which do not use EIP-4626, wrapper adap ## Reference Implementation -See [Solmate EIP-4626](https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol): +See [Solmate EIP-4626](https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol): a minimal and opinionated implementation of the standard with hooks for developers to easily insert custom logic into deposits and withdrawals. See [Vyper EIP-4626](https://github.com/fubuloubu/ERC4626): From 34794c3bb3c52ac2a6b7cf29c3dd7d313e414f7e Mon Sep 17 00:00:00 2001 From: galimba Date: Wed, 25 Sep 2024 20:55:37 +0200 Subject: [PATCH 67/79] Update ERC-7208: Move to Review Merged by EIP-Bot. --- ERCS/erc-7208.md | 6 ++++-- assets/erc-7208/contracts/README.md | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 assets/erc-7208/contracts/README.md diff --git a/ERCS/erc-7208.md b/ERCS/erc-7208.md index 8b4d1d3f23..b175e8dec8 100644 --- a/ERCS/erc-7208.md +++ b/ERCS/erc-7208.md @@ -1,10 +1,10 @@ --- eip: 7208 title: On-Chain Data Container -description: ERC interoperability by abstracting logic away from storage +description: Interoperability by abstracting logic away from storage author: Rachid Ajaja , Alexandros Athanasopulos (@Xaleee), Pavel Rubin (@pash7ka), Sebastian Galimberti Romano (@galimba) discussions-to: https://ethereum-magicians.org/t/erc-7208-on-chain-data-container/14778 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-06-09 @@ -271,6 +271,8 @@ We present an **educational example** implementation showcasing two types of tok **This example has not been audited and should not be used in production environments.** +See [contracts](../assets/eip-7208/contracts/README.md) + ## Security Considerations diff --git a/assets/erc-7208/contracts/README.md b/assets/erc-7208/contracts/README.md new file mode 100644 index 0000000000..2a0ea7707b --- /dev/null +++ b/assets/erc-7208/contracts/README.md @@ -0,0 +1,22 @@ +# Reference implementation of ERC-7208 and usage examples +## List of contracts +### Interfaces +- [IDataIndex](./interfaces/IDataIndex.sol) - Interface of Data Index +- [IDataObject](./interfaces/IDataObject.sol) - Interface of Data Object +- [IDataPointRegistry](./interfaces/IDataPointRegistry.sol) - Interface of Data Point Registry +- [IIDManager](./interfaces/IIDManager.sol) - Interface for buildinq and quering Data Index user identifiers + +### Implementation +- [DataIndex](./DataIndex.sol) - Data Index (implements `IDataIndex` and `IIDManager`) +- [DataPointRegistry](./DataPointRegistry.sol) - Data Point Registry (implements `IDataPointRegistry`) +- [DataPoints](./utils/DataPoints.sol) - Library implementing DataPoint type and its encode/decode functions +- [OmnichainAddresses](./utils/OmnichainAddresses.sol) - Library implementing OmnichainAddress type which combines address and chain id +- [ChainidTools](./utils/ChainidTools.sol) - Library implementing utility functions to work with chain ids + +### Usage examples +- [IFractionTransferEventEmitter](./interfaces/IFractionTransferEventEmitter.sol) - Interface used for DataManagers communication to emit ERC20 Transfer events +- [IFungibleFractionsOperations](./interfaces/IFungibleFractionsOperations.sol) - Interface defines DataObject operations, which can be called by DataManager +- [MinimalisticFungibleFractionsDO](./dataobjects/MinimalisticFungibleFractionsDO.sol) - DataObject implements data storage and related logic for token with Fungible Fractions (like ERC1155) +- [MinimalisticERC1155WithERC20FractionsDataManager](./datamanagers/MinimalisticERC1155WithERC20FractionsDataManager.sol) - DataManager implements token with fungible fractions with ERC1155 interface, linked to a DataManager which implements ERC20 interface for same token +- [MinimalisticERC20FractionDataManager](./datamanagers/MinimalisticERC20FractionDataManager.sol) - implements token with ERC20 interface, linked to a DataManager which implements ERC1155 interface for same token +- [MinimalisticERC20FractionDataManagerFactory](./datamanagers/MinimalisticERC20FractionDataManagerFactory.sol) - factory of DataManagers implementing ERC20 interface for token with fungible fractions \ No newline at end of file From 99e8c6af0bee797c5c6da549fafa8a129eaba81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernani=20S=C3=A3o=20Thiago?= Date: Thu, 26 Sep 2024 15:55:56 -0300 Subject: [PATCH 68/79] Update ERC-7432: Move to Final Merged by EIP-Bot. --- ERCS/erc-7432.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ERCS/erc-7432.md b/ERCS/erc-7432.md index 0708c4c36a..1043f65f67 100644 --- a/ERCS/erc-7432.md +++ b/ERCS/erc-7432.md @@ -4,8 +4,7 @@ title: Non-Fungible Token Roles description: Role Management for NFTs. Enables accounts to share the utility of NFTs via expirable role assignments. author: Ernani São Thiago (@ernanirst), Daniel Lima (@karacurt) discussions-to: https://ethereum-magicians.org/t/eip-7432-non-fungible-token-roles/15298 -status: Last Call -last-call-deadline: 2024-09-17 +status: Final type: Standards Track category: ERC created: 2023-07-14 From 82a7301d4f5d61190063a7b3327568fcdf1a419f Mon Sep 17 00:00:00 2001 From: Christina <156356273+cratiu222@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:29:40 +0300 Subject: [PATCH 69/79] Update ERC-1066: Chore fix docs (#546) * correct spelling erc-1066.md * wrong verb form erc-1077.md * add missing verb erc-1081.md --- ERCS/erc-1066.md | 2 +- ERCS/erc-1077.md | 2 +- ERCS/erc-1081.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-1066.md b/ERCS/erc-1066.md index 7f60fe566e..8b8c2a813a 100644 --- a/ERCS/erc-1066.md +++ b/ERCS/erc-1066.md @@ -236,7 +236,7 @@ Currently unspecified. (Full range reserved) #### `0x7*` TBD -Currently unspecifie. (Full range reserved) +Currently unspecified. (Full range reserved) #### `0x8*` TBD diff --git a/ERCS/erc-1077.md b/ERCS/erc-1077.md index 4ae82ddc2c..ca2a8a91f2 100644 --- a/ERCS/erc-1077.md +++ b/ERCS/erc-1077.md @@ -85,7 +85,7 @@ The fields **MUST** be constructed as this method: The first and second fields are to make it [EIP-191] compliant. Starting a transaction with `byte(0x19)` ensure the signed data from being a [valid ethereum transaction](https://github.com/ethereum/wiki/wiki/RLP). The second argument is a version control byte. The third being the validator address (the account contract address) according to version 0 of [EIP-191]. The remaining arguments being the application specific data for the gas relay: chainID as per [EIP-1344], execution nonce, execution data, agreed gas Price, gas limit of gas relayed call, gas token to pay back and gas relayer authorized to receive the reward. -The [EIP-191] message must be constructed as following: +The [EIP-191] message must be constructed as follows: ```solidity keccak256( abi.encodePacked( diff --git a/ERCS/erc-1081.md b/ERCS/erc-1081.md index f73b2c7011..bbb330361f 100644 --- a/ERCS/erc-1081.md +++ b/ERCS/erc-1081.md @@ -28,7 +28,7 @@ After studying bounties as they've existed for thousands of years (and after imp To implement these steps, a number of functions are needed: - `initializeBounty(address _issuer, address _arbiter, string _data, uint _deadline)`: This is used when deploying a new StandardBounty contract, and is particularly useful when applying the proxy design pattern, whereby bounties cannot be initialized in their constructors. Here, the data string should represent an IPFS hash, corresponding to a JSON object which conforms to the schema (described below). - `fulfillBounty(address[] _fulfillers, uint[] _numerators, uint _denomenator, string _data)`: This is called to submit a fulfillment, submitting a string representing an IPFS hash which contains the deliverable for the bounty. Initially fulfillments could only be submitted by one individual at a time, however users consistently told us they desired to be able to collaborate on fulfillments, thereby allowing the credit for submissions to be shared by several parties. The lines along which eventual payouts are split are determined by the fractions of the submission credited to each fulfiller (using the array of numerators and single denominator). Here, a bounty platform may also include themselves as a collaborator to collect a small fee for matching the bounty with fulfillers. -- `acceptFulfillment(uint _fulfillmentId, StandardToken[] _payoutTokens, uint[] _tokenAmounts)`: This is called by the `issuer` or the `arbiter` to pay out a given fulfillment, using an array of tokens, and an array of amounts of each token to be split among the contributors. This allows for the bounty payout amount to move as it needs to based on incoming contributions (which may be transferred directly to the contract address). It also allows for the easy splitting of a given bounty's balance among several fulfillments, if the need should arise. +- `acceptFulfillment(uint _fulfillmentId, StandardToken[] _payoutTokens, uint[] _tokenAmounts)`: This is called by the `issuer` or the `arbiter` to pay out a given fulfillment, using an array of tokens, and an array of amounts of each token to be split among the contributors. This allows for the bounty payout amount to move as it needs to be based on incoming contributions (which may be transferred directly to the contract address). It also allows for the easy splitting of a given bounty's balance among several fulfillments, if the need should arise. - `drainBounty(StandardToken[] _payoutTokens)`: This may be called by the `issuer` to drain a bounty of it's funds, if the need should arise. - `changeBounty(address _issuer, address _arbiter, string _data, uint _deadline)`: This may be called by the `issuer` to change the `issuer`, `arbiter`, `data`, and `deadline` fields of their bounty. - `changeIssuer(address _issuer)`: This may be called by the `issuer` to change to a new `issuer` if need be From e1b9b3ff82e7580379a62e3b0ae318414e1a2114 Mon Sep 17 00:00:00 2001 From: Jeroen <1748621+hieronx@users.noreply.github.com> Date: Fri, 27 Sep 2024 21:07:44 +0200 Subject: [PATCH 70/79] Update ERC-7741: Update ERC7741 (#560) * Move ERC7575 to Last Call * Clarifications * Fix reference implementation, add pipe explanation * Fix typo * Move ERC7540 to Last Call * requester => controller * chore: add author * fix: undo status change * comments * chore: some comments * Clarify request id * fix: explanation on requestRedeem * Swap nonce and deadline, update ERC165 id --------- Co-authored-by: Timepunk <45543880+0xTimepunk@users.noreply.github.com> Co-authored-by: Joey Santoro --- ERCS/erc-7741.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ERCS/erc-7741.md b/ERCS/erc-7741.md index 7c7c6f57d7..47ef38948c 100644 --- a/ERCS/erc-7741.md +++ b/ERCS/erc-7741.md @@ -77,10 +77,10 @@ MUST return `true`. type: address - name: approved type: bool - - name: deadline - type: uint256 - name: nonce type: bytes32 + - name: deadline + type: uint256 - name: signature type: bytes @@ -139,7 +139,7 @@ Returns the `DOMAIN_SEPARATOR` as defined according to EIP-712. The `DOMAIN_SEPA Smart contracts implementing this standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. -Contracts MUST return the constant value `true` if `0x7a7911eb` is passed through the `interfaceID` argument. +Contracts MUST return the constant value `true` if `0xa9e50872` is passed through the `interfaceID` argument. ## Rationale @@ -155,7 +155,7 @@ The main difference is using `bytes32` vs `uint256`, which enables unordered non // This code snippet is incomplete pseudocode used for example only and is no way intended to be used in production or guaranteed to be secure bytes32 public constant AUTHORIZE_OPERATOR_TYPEHASH = - keccak256("AuthorizeOperator(address controller,address operator,bool approved,uint256 deadline,bytes32 nonce)"); + keccak256("AuthorizeOperator(address controller,address operator,bool approved,bytes32 nonce,uint256 deadline)"); mapping(address owner => mapping(bytes32 nonce => bool used)) authorizations; @@ -171,8 +171,8 @@ The main difference is using `bytes32` vs `uint256`, which enables unordered non address controller, address operator, bool approved, - uint256 deadline, bytes32 nonce, + uint256 deadline, bytes memory signature ) external returns (bool success) { require(block.timestamp <= deadline, "ERC7540Vault/expired"); @@ -185,7 +185,7 @@ The main difference is using `bytes32` vs `uint256`, which enables unordered non abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), - keccak256(abi.encode(AUTHORIZE_OPERATOR_TYPEHASH, controller, operator, approved, deadline, nonce)) + keccak256(abi.encode(AUTHORIZE_OPERATOR_TYPEHASH, controller, operator, approved, nonce, deadline)) ) ); From 0fc375d6412fcab8e1de51131ba2f344fad5f32c Mon Sep 17 00:00:00 2001 From: Dexaran Date: Sat, 28 Sep 2024 00:45:36 +0100 Subject: [PATCH 71/79] Update ERC-7417: Update ERC-7417 Merged by EIP-Bot. --- ERCS/erc-7417.md | 672 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 570 insertions(+), 102 deletions(-) diff --git a/ERCS/erc-7417.md b/ERCS/erc-7417.md index 33b8b711af..5f2af30f98 100644 --- a/ERCS/erc-7417.md +++ b/ERCS/erc-7417.md @@ -15,11 +15,15 @@ requires: 20, 165, 223 There are multiple token standards on Ethereum chain currently. This EIP introduces a concept of cross-standard interoperability by creating a service that allows [ERC-20](./eip-20.md) tokens to be upgraded to [ERC-223](./eip-223.md) tokens anytime. [ERC-223](./eip-223.md) tokens can be converted back to [ERC-20](./eip-20.md) version without any restrictions to avoid any problems with backwards compatibility and allow different standards to co-exist and become interoperable and interchangeable. -To perform the conversion, the user must send tokens of one standard to the Converter contract and he will automatically receive tokens of another standard. +In order to perform the conversion, a user must deposit tokens of one standard to the Converter contract and it will automatically send tokens of another standard back. ## Motivation -When an ERC-20 contract is upgraded, finding the new address introduces risk. This proposal creates a service that performs token conversion and prevents potentially unsafe implementations from spreading. +This proposal introduces a concept of token standard upgrading procedure driven by a specialized smart-contract which can convert tokens of one standard to another at any time as well as create an alternative version of any existing token of the older standard. + +Currently some tokens are available on different chains in different standards, for example most exchanges support [ERC-20](./eip-20.md) USDT, TRX USDT, BEP-20 USDT and all this tokens are in fact the same USDT token. This proposal is intended to introduce a concept where there can be a [ERC-20](./eip-20.md) USDT and [ERC-223](./eip-223.md) USDT available on Ethereum mainnet at the same time and both can co-exist. + +The address of the deployed Token Converter must be described here as to solve the trust issues for the token developers and help them figure out a proper way of interacting with the Converter. ## Specification @@ -41,21 +45,54 @@ Converter contract MUST accept deposits of [ERC-223](./eip-223.md) tokens and se #### Conver contract methods -##### `getWrapperFor` +##### `getERC20WrapperFor` + +```solidity +function getERC20WrapperFor(address _token) public view returns (address) +``` + +Returns the address of the [ERC-20](./eip-20.md) wrapper for a given token address. Returns `0x0` if there is no [ERC-20](./eip-20.md) version for the provided token address. There can be exactly one wrapper for any given [ERC-223](./eip-223.md) token address created by the Token Converter contract. + +##### `getERC223WrapperFor` ```solidity -function getWrapperFor(address _erc20Token) public view returns (address) +function getERC223WrapperFor(address _token) public view returns (address) ``` -Returns the address of the [ERC-223](./eip-223.md) wrapper for a given [ERC-20](./eip-20.md) original token. Returns `0x0` if there is no [ERC-223](./eip-223.md) version for the provided [ERC-20](./eip-20.md) token address. There MUST be exactly one wrapper for any given [ERC-20](./eip-20.md) token address created by the Token Converter contract. +Returns the address of the [ERC-223](./eip-223.md) wrapper for a given token address. Returns `0x0` if there is no [ERC-223](./eip-223.md) version for the provided token address. There can be exactly one [ERC-223](./eip-223.md) wrapper for any given [ERC-20](./eip-20.md) token address created by the Token Converter contract. -##### `getOriginFor` +##### `getERC20OriginFor` ```solidity -function getOriginFor(address _erc223Token) public view returns (address) +function getERC20OriginFor(address _erc223Token) public view returns (address) ``` -Returns the address of the original [ERC-20](./eip-20.md) token for a given [ERC-223](./eip-223.md) wrapper. Returns `0x0` if the provided `_erc223Token` is not an address of any [ERC-223](./eip-223.md) wrapper created by the Token Converter contract. +Returns the address of the original [ERC-20](./eip-20.md) token for the provided [ERC-223](./eip-223.md) wrapper. Returns `0x0` if the provided `_erc223Token` is not an address of any [ERC-223](./eip-223.md) wrapper created by the Token Converter contract. + +##### `getERC223OriginFor` + +```solidity +function getERC223OriginFor(address _erc20Token) public view returns (address) +``` + +Returns the address of the original [ERC-223](./eip-223.md) token for the provided [ERC-20](./eip-20.md) wrapper. Returns `0x0` if the provided `_erc20Token` is not an address of any wrapper created by the Token Converter contract. + +##### `predictWrapperAddress` + +```solidity +function predictWrapperAddress(address _token, + bool _isERC20 // Is the provided _token a ERC-20 or not? + // If it is set as ERC-20 then we will predict the address of a + // ERC-223 wrapper for that token. + // Otherwise we will predict ERC-20 wrapper address. + ) view external returns (address) +``` + +Wrapper contracts are deployed via `CREATE2` opcode and it is possible to predict the address of a wrapper which is not yet deployed. The address of a wrapper contract depends on the bytecode therefore it is necessary to specify if the address of wrapper [ERC-20](./eip-20.md) or wrapper [ERC-223](./eip-223.md) must be predicted. + +Providing `_token` address and `_isERC20 = false` will result in [ERC-20](./eip-20.md) wrapper address being predicted. + +Providing `_token` address and `_isERC20 = true` will result in [ERC-223](./eip-223.md) wrapper address being predicted. ##### `createERC223Wrapper` @@ -63,19 +100,66 @@ Returns the address of the original [ERC-20](./eip-20.md) token for a given [ERC function createERC223Wrapper(address _erc20Token) public returns (address) ``` -Creates a new [ERC-223](./eip-223.md) wrapper for a given `_erc20Token` if it does not exist yet. Reverts the transaction if the wrapper already exist. Returns the address of the new wrapper token contract on success. +Creates a new [ERC-223](./eip-223.md) wrapper for a given `_erc20Token` if it does not exist yet. Reverts the transaction if the wrapper already exist. Returns the address of the new wrapper token contract on success. Reverts if `_erc223Token` is a wrapper created by the Converter. + +The deployed contract will be a standard [ERC-223](./eip-223.md) token with `approve` and `transferFrom` functions implemented for backwards compatibility. + +All [ERC-223](./eip-223.md) wrappers deployed by the Converter will have `standard() pure returns (bytes32)` function implemented which returns `223`. This serves further token standard introspection as [ERC-165](./eip-165.md) may not be reliable when dealing with identifying the internal logic implemented within `transfer` function of a token. -##### `convertERC20toERC223` +NOTE: This function does not verify the standard of `_erc20Token` because there is no reliable method of introspection available which could guarantee that the provided token implements a particular standard. As the result it is possible to create a [ERC-223](./eip-223.md) wrapper for an original [ERC-223](./eip-223.md) token. + +##### `createERC20Wrapper` ```solidity -function convertERC20toERC223(address _erc20token, uint256 _amount) public returns (bool) +function createERC20Wrapper(address _erc223Token) public returns (address) ``` -Withdraws `_amount` of [ERC-20](./eip-20.md) token from the transaction senders balance with `transferFrom` function. Sends the `_amount` of [ERC-223](./eip-223.md) wrapper tokens to the sender of the transaction. Stores the original tokens at the balance of the Token Converter contract for future claims. Returns `true` on success. The Token Converter must keep record of the amount of [ERC-20](./eip-20.md) tokens that were deposited with `convertERC20toERC223` function because it is possible to deposit [ERC-20](./eip-20.md) tokens to any contract by directly sending them with `transfer` function. +Creates a new [ERC-20](./eip-20.md) wrapper for a given `_erc223Token` if it does not exist yet. Reverts the transaction if the wrapper already exist. Returns the address of the new wrapper token contract on success. Reverts if `_erc223Token` is a wrapper created by the Converter. + +NOTE: This function does not verify the standard of `_erc223Token` because there is no reliable method of introspection available which could guarantee that the provided token implements a particular standard. As the result it is possible to create a [ERC-20](./eip-20.md) wrapper for an original [ERC-20](./eip-20.md) token. + +##### `wrapERC20toERC223` + +```solidity +function wrapERC20toERC223(address _ERC20token, uint256 _amount) public returns (bool) +``` + +Withdraws `_amount` of [ERC-20](./eip-20.md) tokens from the transaction sender with `transferFrom` function. Delivers the `_amount` of [ERC-223](./eip-223.md) wrapper tokens to the sender of the transaction. Stores the original tokens at the balance of the Token Converter contract for future claims. Returns `true` on success. The Token Converter must keep record of the amount of [ERC-20](./eip-20.md) tokens that were deposited with `wrapERC20toERC223` function because it is possible to deposit [ERC-20](./eip-20.md) tokens to any contract by directly sending them with `transfer` function. If there is no [ERC-223](./eip-223.md) wrapper for the `_ERC20token` then creates it by calling a `createERC223Wrapper(_erc20toke)` function. -If the provided `_erc20token` address is an address of a [ERC-223](./eip-223.md) wrapper reverts the transaction. +There is no special function to unwrap [ERC-223](./eip-223.md) wrappers to [ERC-20](./eip-20.md) origin as this logic is implemented in the `tokenReceived` function of the Converter. + +##### `unwrapERC20toERC223` + +```solidity +function unwrapERC20toERC223(address _ERC20token, uint256 _amount) public returns (bool) +``` + +Withdraws `_amount` of [ERC-20](./eip-20.md) tokens from the transaction sender with `transferFrom` function. Delivers the `_amount` of [ERC-223](./eip-223.md) wrapper tokens to the sender of the transaction. Stores the original tokens at the balance of the Token Converter contract for future claims. Returns `true` on success. The Token Converter must keep record of the amount of [ERC-20](./eip-20.md) tokens that were deposited with `wrapERC20toERC223` function because it is possible to deposit [ERC-20](./eip-20.md) tokens to any contract by directly sending them with `transfer` function. + +If there is no [ERC-223](./eip-223.md) wrapper for the `_ERC20token` then creates it by calling a `createERC223Wrapper(_erc20toke)` function. + + +##### `convertERC20` + +```solidity +function convertERC20(address _token, uint256 _amount) public returns (bool) +``` + +Automatically determines if the provided [ERC-20](./eip-20.md) token is a wrapper or not. If it is a wrapper then executes `unwrapERC20toERC223` function. If the provided token is an origin then executes `wrapERC20toERC223` function. + +This function is implemented to significantly simplify the workflow of services that integrate both versions of one token in the same contract and need to automatically convert tokens through the Converter. + +##### `isWrapper` + +```solidity +function isWrapper(address _token) public view returns (bool) +``` + +Returns `true` if the provided `_token` address is an address of a wrapper created by the Converter. + +NOTE: This function does not identify the standard of a `_token`. There can be exactly one origin for any wrapper created by the Converter. However an original token can have two wrappers, one of each standard. ##### `tokenReceived` @@ -83,23 +167,23 @@ If the provided `_erc20token` address is an address of a [ERC-223](./eip-223.md) function tokenReceived(address _from, uint _value, bytes memory _data) public override returns (bytes4) ``` -This is a standard [ERC-223](./eip-223.md) transaction handler function and it is called by the [ERC-223](./eip-223.md) token contract when `_from` is sending `_value` of [ERC-223](./eip-223.md) tokens to `address(this)` address. In the scope of this function `msg.sender` is the address of the [ERC-223](./eip-223.md) token contract and `_from` is the initiator of the transaction. +This is a standard [ERC-223](./eip-223.md) transaction handler function and it is called by the [ERC-223](./eip-223.md) token contract when `_from` is sending `_value` of [ERC-223](./eip-223.md) tokens to `address(this)` address. In the scope of this function `msg.sender` is the address of the [ERC-223](./eip-223.md) token contract and `_from` is the sender of the token transfer. -If `msg.sender` is an address of [ERC-223](./eip-223.md) wrapper created by the Token Converter then `_value` of [ERC-20](./eip-20.md) original token must be sent to the `_from` address. +Automatically determines -If `msg.sender` is not an address of any [ERC-223](./eip-223.md) wrapper known to the Token Converter then revert the transaction thus returning any `ERC-223` tokens back to the sender. +If `msg.sender` is an address of [ERC-223](./eip-223.md) wrapper created by the Token Converter then `_value` of [ERC-20](./eip-20.md) original token must be sent to the `_from` address. -This is the function that MUST be used to convert [ERC-223](./eip-223.md) wrapper tokens back to original [ERC-20](./eip-20.md) tokens. This function is automatically executed when [ERC-223](./eip-223.md) tokens are sent to the address of the Token Converter. If any arbitrary [ERC-223](./eip-223.md) token is sent to the Token Converter it will be rejected. +If `msg.sender` is not an address of any [ERC-223](./eip-223.md) wrapper known to the Token Converter then it is considered a [ERC-223](./eip-223.md) origin and `_value` amount of [ERC-20](./eip-20.md) wrapper tokens must be sent to the `_from` address. If the [ERC-20](./eip-20.md) wrapper for the `msg.sender` token does not exist then create it first. Returns `0x8943ec02`. -##### `rescueERC20` +##### `extractStuckERC20` ```solidity -function rescueERC20(address _token) external +function extractStuckERC20(address _token) ``` -This function allows to extract the [ERC-20](./eip-20.md) tokens that were directly deposited to the contract with `transfer` function to prevent users who may send tokens by mistake from permanently freezing their assets. Since the Token Converter calculates the amount of tokens that were deposited legitimately with `convertERC20toERC223` function it is always possible to calculate the amount of "accidentally deposited tokens" by subtracting the recorded amount from the returned value of the `balanceOf( address(this) )` function called on the [ERC-20](./eip-20.md) token contract. +This function allows to extract the [ERC-20](./eip-20.md) tokens that were directly deposited to the contract with `transfer` function to prevent users who may send tokens by mistake from permanently losing their tokens. Since the Token Converter calculates the amount of tokens that were deposited legitimately with `convertERC20toERC223` function it is always possible to calculate the amount of "accidentally deposited tokens" by subtracting the recorded amount from the returned value of the `balanceOf( address(this) )` function called on the [ERC-20](./eip-20.md) token contract. ### Converting [ERC-20](./eip-20.md) tokens to [ERC-223](./eip-223.md) @@ -117,15 +201,27 @@ In order to convert [ERC-20](./eip-20.md) tokens to [ERC-223](./eip-223.md) the ## Rationale - +For example it was a common case with [ERC-20](./eip-20.md) where developers could implement custom logic of the `transfer` function and mess the return values. The [ERC-20](./eip-20.md) specification declares that a `transfer` function MUST return a `bool` value, however in practice we have three different types of [ERC-20](./eip-20.md) tokens which are not compatible with each other: -TBD +1. [ERC-20](./eip-20.md) tokens that return `true` on success and revert on an error. +2. [ERC-20](./eip-20.md) tokens that return `true` on success and `false` on an error without reverting the transaction. +3. [ERC-20](./eip-20.md) tokens that don't have return values and revert on an error. + +Technically the third category of tokens is not compatible with [ERC-20](./eip-20.md) standard. However, USDT token deployed on Ethereum mainnet at `0xdac17f958d2ee523a2206206994597c13d831ec7` address does not implement return values and it is one of the most used tokens and it is not an option to deny supporting USDT due to it's improper implementation of the standard. + +The Token Converter eliminates the issue where different development teams may implement the standard with slight modifications and result in a situation where we would have different versions of the same standard on the mainnet. + +At the same time the Converter enables the concurrent token support in other smart-contracts, such as decentralized exchanges. The Converter can guarantee that a pair of two tokens one of which is a wrapper for another is in fact the same token that can be converted from one standard to another at any time. This enables the creation of liquidity pools where two different tokens are dealt with as if they were one token while in fact these are exactly one token available in different standards. ## Backwards Compatibility @@ -136,7 +232,389 @@ This service is the first of its kind and therefore does not have any backwards ## Reference Implementation ```solidity - address public ownerMultisig; + +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity =0.8.19; + +library Address { + function isContract(address account) internal view returns (bool) { + // This method relies on extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + + uint256 size; + // solhint-disable-next-line no-inline-assembly + assembly { size := extcodesize(account) } + return size > 0; + } +} + +interface IERC20 { + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address recipient, uint256 amount) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +interface IERC20Metadata is IERC20 { + /// @return The name of the token + function name() external view returns (string memory); + + /// @return The symbol of the token + function symbol() external view returns (string memory); + + /// @return The number of decimal places the token has + function decimals() external view returns (uint8); +} + +abstract contract IERC223Recipient { + function tokenReceived(address _from, uint _value, bytes memory _data) public virtual returns (bytes4) + { + return 0x8943ec02; + } +} + +abstract contract ERC165 { + /* + * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 + */ + bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; + mapping(bytes4 => bool) private _supportedInterfaces; + + constructor () { + // Derived contracts need only register support for their own interfaces, + // we register support for ERC165 itself here + _registerInterface(_INTERFACE_ID_ERC165); + } + function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { + return _supportedInterfaces[interfaceId]; + } + function _registerInterface(bytes4 interfaceId) internal virtual { + require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); + _supportedInterfaces[interfaceId] = true; + } +} + +abstract contract IERC223 { + function name() public view virtual returns (string memory); + function symbol() public view virtual returns (string memory); + function decimals() public view virtual returns (uint8); + function totalSupply() public view virtual returns (uint256); + function balanceOf(address who) public virtual view returns (uint); + function transfer(address to, uint value) public virtual returns (bool success); + function transfer(address to, uint value, bytes calldata data) public payable virtual returns (bool success); + event Transfer(address indexed from, address indexed to, uint value, bytes data); +} + +interface standardERC20 +{ + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 value) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); +} + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC223WrapperToken { + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function decimals() external view returns (uint8); + function standard() external view returns (string memory); + function origin() external view returns (address); + + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 value) external payable returns (bool); + function transfer(address to, uint256 value, bytes calldata data) external payable returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); + + function mint(address _recipient, uint256 _quantity) external; + function burn(address _recipient, uint256 _quantity) external; +} + +interface IERC20WrapperToken { + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function decimals() external view returns (uint8); + function standard() external view returns (string memory); + function origin() external view returns (address); + + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 value) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); + + function mint(address _recipient, uint256 _quantity) external; + function burn(address _recipient, uint256 _quantity) external; +} + +contract ERC20Rescue +{ + // ERC-20 tokens can get stuck on a contracts balance due to lack of error handling. + // + // The author of the ERC-7417 can extract ERC-20 tokens if they are mistakenly sent + // to the wrapper-contracts balance. + // Contact dexaran@ethereumclassic.org + address public extractor = 0x01000B5fE61411C466b70631d7fF070187179Bbf; + + function safeTransfer(address token, address to, uint value) internal { + // bytes4(keccak256(bytes('transfer(address,uint256)'))); + (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); + require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); + } + + function rescueERC20(address _token, uint256 _amount) external + { + safeTransfer(_token, extractor, _amount); + } +} + +contract ERC223WrapperToken is IERC223, ERC165, ERC20Rescue +{ + address public creator = msg.sender; + address private wrapper_for; + + mapping(address account => mapping(address spender => uint256)) private allowances; + + event Transfer(address indexed from, address indexed to, uint256 amount); + event TransferData(bytes data); + event Approval(address indexed owner, address indexed spender, uint256 amount); + + function set(address _wrapper_for) external + { + require(msg.sender == creator); + wrapper_for = _wrapper_for; + } + + uint256 private _totalSupply; + + mapping(address => uint256) private balances; // List of user balances. + + function totalSupply() public view override returns (uint256) { return _totalSupply; } + function balanceOf(address _owner) public view override returns (uint256) { return balances[_owner]; } + + + /** + * @dev The ERC165 introspection function. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return + interfaceId == type(IERC20).interfaceId || + interfaceId == type(standardERC20).interfaceId || + interfaceId == type(IERC223WrapperToken).interfaceId || + interfaceId == type(IERC223).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @dev Standard ERC-223 transfer function. + * Calls _to if it is a contract. Does not transfer tokens to contracts + * which do not explicitly declare the tokenReceived function. + * @param _to - transfer recipient. Can be contract or EOA. + * @param _value - the quantity of tokens to transfer. + * @param _data - metadata to send alongside the transaction. Can be used to encode subsequent calls in the recipient. + */ + function transfer(address _to, uint _value, bytes calldata _data) public payable override returns (bool success) + { + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(Address.isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data); + } + if (msg.value > 0) payable(_to).transfer(msg.value); + emit Transfer(msg.sender, _to, _value, _data); + emit Transfer(msg.sender, _to, _value); // Old ERC-20 compatible event. Added for backwards compatibility reasons. + + return true; + } + + /** + * @dev Standard ERC-223 transfer function without _data parameter. It is supported for + * backwards compatibility with ERC-20 services. + * Calls _to if it is a contract. Does not transfer tokens to contracts + * which do not explicitly declare the tokenReceived function. + * @param _to - transfer recipient. Can be contract or EOA. + * @param _value - the quantity of tokens to transfer. + */ + function transfer(address _to, uint _value) public override returns (bool success) + { + bytes memory _empty = hex"00000000"; + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(Address.isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty); + } + emit Transfer(msg.sender, _to, _value, _empty); + emit Transfer(msg.sender, _to, _value); // Old ERC-20 compatible event. Added for backwards compatibility reasons. + + return true; + } + + function name() public view override returns (string memory) { return IERC20Metadata(wrapper_for).name(); } + function symbol() public view override returns (string memory) { return string.concat(IERC20Metadata(wrapper_for).name(), "223"); } + function decimals() public view override returns (uint8) { return IERC20Metadata(wrapper_for).decimals(); } + function standard() public pure returns (uint32) { return 223; } + function origin() public view returns (address) { return wrapper_for; } + + + /** + * @dev Minting function which will only be called by the converter contract. + * @param _recipient - the address which will receive tokens. + * @param _quantity - the number of tokens to create. + */ + function mint(address _recipient, uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can mint wrapper tokens."); + balances[_recipient] += _quantity; + _totalSupply += _quantity; + } + + /** + * @dev Burning function which will only be called by the converter contract. + * @param _quantity - the number of tokens to destroy. TokenConverter can only destroy tokens on it's own address. + * Only the token converter is allowed to burn wrapper-tokens. + */ + function burn(uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can destroy wrapper tokens."); + balances[msg.sender] -= _quantity; + _totalSupply -= _quantity; + } + + // ERC-20 functions for backwards compatibility. + + function allowance(address owner, address spender) public view virtual returns (uint256) { + return allowances[owner][spender]; + } + + function approve(address _spender, uint _value) public returns (bool) { + + // Safety checks. + require(_spender != address(0), "ERC-223: Spender error."); + + allowances[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + + return true; + } + + function transferFrom(address _from, address _to, uint _value) public returns (bool) { + + require(allowances[_from][msg.sender] >= _value, "ERC-223: Insufficient allowance."); + + balances[_from] -= _value; + allowances[_from][msg.sender] -= _value; + balances[_to] += _value; + + emit Transfer(_from, _to, _value); + + return true; + } +} + +contract ERC20WrapperToken is IERC20, ERC165, ERC20Rescue +{ + address public creator = msg.sender; + address public wrapper_for; + + mapping(address account => mapping(address spender => uint256)) private allowances; + + function set(address _wrapper_for) external + { + require(msg.sender == creator); + wrapper_for = _wrapper_for; + } + + uint256 private _totalSupply; + mapping(address => uint256) private balances; // List of user balances. + + + function balanceOf(address _owner) public view override returns (uint256) { return balances[_owner]; } + + function name() public view returns (string memory) { return IERC20Metadata(wrapper_for).name(); } + function symbol() public view returns (string memory) { return string.concat(IERC223(wrapper_for).name(), "20"); } + function decimals() public view returns (uint8) { return IERC20Metadata(wrapper_for).decimals(); } + function totalSupply() public view override returns (uint256) { return _totalSupply; } + function origin() public view returns (address) { return wrapper_for; } + + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return + interfaceId == type(IERC20).interfaceId || + interfaceId == type(IERC20WrapperToken).interfaceId || + super.supportsInterface(interfaceId); + } + + function transfer(address _to, uint _value) public override returns (bool success) + { + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + emit Transfer(msg.sender, _to, _value); + return true; + } + + function mint(address _recipient, uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can mint wrapper tokens."); + balances[_recipient] += _quantity; + _totalSupply += _quantity; + } + + function burn(address _from, uint256 _quantity) external + { + require(msg.sender == creator, "Wrapper Token: Only the creator contract can destroy wrapper tokens."); + balances[_from] -= _quantity; + _totalSupply -= _quantity; + } + + function allowance(address owner, address spender) public view virtual returns (uint256) { + return allowances[owner][spender]; + } + + function approve(address _spender, uint _value) public returns (bool) { + + // Safety checks. + + require(_spender != address(0), "ERC-20: Spender error."); + + allowances[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + + return true; + } + + function transferFrom(address _from, address _to, uint _value) public returns (bool) { + + require(allowances[_from][msg.sender] >= _value, "ERC-20: Insufficient allowance."); + + balances[_from] -= _value; + allowances[_from][msg.sender] -= _value; + balances[_to] += _value; + + emit Transfer(_from, _to, _value); + + return true; + } +} + +contract TokenStandardConverter is IERC223Recipient +{ + event ERC223WrapperCreated(address indexed _token, address indexed _ERC223Wrapper); + event ERC20WrapperCreated(address indexed _token, address indexed _ERC20Wrapper); mapping (address => ERC223WrapperToken) public erc223Wrappers; // A list of token wrappers. First one is ERC-20 origin, second one is ERC-223 version. mapping (address => ERC20WrapperToken) public erc20Wrappers; @@ -145,24 +623,14 @@ This service is the first of its kind and therefore does not have any backwards mapping (address => address) public erc20Origins; mapping (address => uint256) public erc20Supply; // Token => how much was deposited. - function getERC20WrapperFor(address _token) public view returns (address, string memory) + function getERC20WrapperFor(address _token) public view returns (address) { - if ( address(erc20Wrappers[_token]) != address(0) ) - { - return (address(erc20Wrappers[_token]), "ERC-20"); - } - - return (address(0), "Error"); + return address(erc20Wrappers[_token]); } - function getERC223WrapperFor(address _token) public view returns (address, string memory) + function getERC223WrapperFor(address _token) public view returns (address) { - if ( address(erc223Wrappers[_token]) != address(0) ) - { - return (address(erc223Wrappers[_token]), "ERC-223"); - } - - return (address(0), "Error"); + return address(erc223Wrappers[_token]); } function getERC20OriginFor(address _token) public view returns (address) @@ -175,7 +643,33 @@ This service is the first of its kind and therefore does not have any backwards return (address(erc223Origins[_token])); } - function tokenReceived(address _from, uint _value, bytes memory _data) public override returns (bytes4) + function predictWrapperAddress(address _token, + bool _isERC20 // Is the provided _token a ERC-20 or not? + // If it is set as ERC-20 then we will predict the address of a + // ERC-223 wrapper for that token. + // Otherwise we will predict ERC-20 wrapper address. + ) view external returns (address) + { + bytes memory _bytecode; + if(_isERC20) + { + _bytecode= type(ERC223WrapperToken).creationCode; + } + else + { + _bytecode= type(ERC20WrapperToken).creationCode; + } + + bytes32 hash = keccak256( + abi.encodePacked( + bytes1(0xff), address(this), keccak256(abi.encode(_token)), keccak256(_bytecode) + ) + ); + + return address(uint160(uint(hash))); + } + + function tokenReceived(address _from, uint _value, bytes memory /* _data */) public override returns (bytes4) { require(erc223Origins[msg.sender] == address(0), "Error: creating wrapper for a wrapper token."); // There are two possible cases: @@ -187,12 +681,11 @@ This service is the first of its kind and therefore does not have any backwards // Origin for deposited token exists. // Unwrap ERC-223 wrapper. + erc20Supply[erc20Origins[msg.sender]] -= _value; safeTransfer(erc20Origins[msg.sender], _from, _value); - erc20Supply[erc20Origins[msg.sender]] -= _value; - //erc223Wrappers[msg.sender].burn(_value); ERC223WrapperToken(msg.sender).burn(_value); - + return this.tokenReceived.selector; } // Otherwise origin for the sender token doesn't exist @@ -204,7 +697,7 @@ This service is the first of its kind and therefore does not have any backwards // Create ERC-20 wrapper if it doesn't exist. createERC20Wrapper(msg.sender); } - + // Mint ERC-20 wrapper tokens for the deposited ERC-223 token // if the ERC-20 wrapper didn't exist then it was just created in the above statement. erc20Wrappers[msg.sender].mint(_from, _value); @@ -214,38 +707,31 @@ This service is the first of its kind and therefore does not have any backwards function createERC223Wrapper(address _token) public returns (address) { require(address(erc223Wrappers[_token]) == address(0), "ERROR: Wrapper exists"); - require(getERC20OriginFor(_token) == address(0), "ERROR: 20 wrapper creation"); - require(getERC223OriginFor(_token) == address(0), "ERROR: 223 wrapper creation"); - - ERC223WrapperToken _newERC223Wrapper = new ERC223WrapperToken(_token); + require(!isWrapper(_token), "Error: Creating wrapper for a wrapper token"); + + ERC223WrapperToken _newERC223Wrapper = new ERC223WrapperToken{salt: keccak256(abi.encode(_token))}(); + _newERC223Wrapper.set(_token); erc223Wrappers[_token] = _newERC223Wrapper; erc20Origins[address(_newERC223Wrapper)] = _token; + emit ERC223WrapperCreated(_token, address(_newERC223Wrapper)); return address(_newERC223Wrapper); } function createERC20Wrapper(address _token) public returns (address) { require(address(erc20Wrappers[_token]) == address(0), "ERROR: Wrapper already exists."); - require(getERC20OriginFor(_token) == address(0), "ERROR: 20 wrapper creation"); - require(getERC223OriginFor(_token) == address(0), "ERROR: 223 wrapper creation"); + require(!isWrapper(_token), "Error: Creating wrapper for a wrapper token"); - ERC20WrapperToken _newERC20Wrapper = new ERC20WrapperToken(_token); + ERC20WrapperToken _newERC20Wrapper = new ERC20WrapperToken{salt: keccak256(abi.encode(_token))}(); + _newERC20Wrapper.set(_token); erc20Wrappers[_token] = _newERC20Wrapper; erc223Origins[address(_newERC20Wrapper)] = _token; + emit ERC20WrapperCreated(_token, address(_newERC20Wrapper)); return address(_newERC20Wrapper); } - function depositERC20(address _token, uint256 _amount) public returns (bool) - { - if(erc223Origins[_token] != address(0)) - { - return unwrapERC20toERC223(_token, _amount); - } - else return wrapERC20toERC223(_token, _amount); - } - function wrapERC20toERC223(address _ERC20token, uint256 _amount) public returns (bool) { // If there is no active wrapper for a token that user wants to wrap @@ -256,14 +742,12 @@ This service is the first of its kind and therefore does not have any backwards } uint256 _converterBalance = IERC20(_ERC20token).balanceOf(address(this)); // Safety variable. safeTransferFrom(_ERC20token, msg.sender, address(this), _amount); - - erc20Supply[_ERC20token] += _amount; - require( - IERC20(_ERC20token).balanceOf(address(this)) - _amount == _converterBalance, - "ERROR: The transfer have not subtracted tokens from callers balance."); + _amount = IERC20(_ERC20token).balanceOf(address(this)) - _converterBalance; + erc20Supply[_ERC20token] += _amount; erc223Wrappers[_ERC20token].mint(msg.sender, _amount); + return true; } @@ -273,48 +757,30 @@ This service is the first of its kind and therefore does not have any backwards require(erc223Origins[_ERC20token] != address(0), "Error: provided token is not a ERC-20 wrapper."); ERC20WrapperToken(_ERC20token).burn(msg.sender, _amount); - IERC223(erc223Origins[_ERC20token]).transfer(msg.sender, _amount); + + safeTransfer(erc223Origins[_ERC20token], msg.sender, _amount); return true; } - function isWrapper(address _token) public view returns (bool) - { - return erc20Origins[_token] != address(0) || erc223Origins[_token] != address(0); - } - -/* - function convertERC223toERC20(address _from, uint256 _amount) public returns (bool) + function convertERC20(address _token, uint256 _amount) public returns (bool) { - // If there is no active wrapper for a token that user wants to wrap - // then create it. - if(address(erc20Wrappers[msg.sender]) == address(0)) - { - createERC223Wrapper(msg.sender); - } - - erc20Wrappers[msg.sender].mint(_from, _amount); - return true; + if(isWrapper(_token)) return unwrapERC20toERC223(_token, _amount); + else return wrapERC20toERC223(_token, _amount); } -*/ - function rescueERC20(address _token) external { - require(msg.sender == ownerMultisig, "ERROR: Only owner can do this."); - uint256 _stuckTokens = IERC20(_token).balanceOf(address(this)) - erc20Supply[_token]; - safeTransfer(_token, msg.sender, IERC20(_token).balanceOf(address(this))); + function isWrapper(address _token) public view returns (bool) + { + return erc20Origins[_token] != address(0) || erc223Origins[_token] != address(0); } - function transferOwnership(address _newOwner) public + function extractStuckERC20(address _token) external { - require(msg.sender == ownerMultisig, "ERROR: Only owner can call this function."); - ownerMultisig = _newOwner; + require(msg.sender == address(0x01000B5fE61411C466b70631d7fF070187179Bbf)); + + safeTransfer(_token, address(0x01000B5fE61411C466b70631d7fF070187179Bbf), IERC20(_token).balanceOf(address(this)) - erc20Supply[_token]); } - // ************************************************************ - // Functions that address problems with tokens that pretend to be ERC-20 - // but in fact are not compatible with the ERC-20 standard transferring methods. - // EIP20 https://eips.ethereum.org/EIPS/eip-20 - // ************************************************************ function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); @@ -326,16 +792,18 @@ This service is the first of its kind and therefore does not have any backwards (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } - +} ``` ## Security Considerations -1. While it is possible to implement a service that converts any token standard to any other standard - it is better to keep different standard convertors separate from one another as different standards may contain specific logic. Therefore this proposal focuses on [ERC-20](./eip-20.md) to [ERC-223](./eip-223.md) conversion methods. -2. [ERC-20](./eip-20.md) tokens can be deposited to any contract directly with `transfer` function. This may result in a permanent loss of tokens because it is not possible to recognize this transaction on the recipients side. `rescueERC20` function is implemented to address this problem. +1. While it is possible to implement a service that converts any token standard to any other standard - it is better to keep different standard convertors separate from one another as different standards may contain specific logic and therefore require different conversion approach. This proposal focuses on [ERC-20](./eip-20.md) and [ERC-223](./eip-223.md) upgradeability. +2. [ERC-20](./eip-20.md) tokens can be deposited to any contract directly with `transfer` function. This may result in a permanent loss of tokens because it is not possible to recognize this transaction on the recipients side. Therefore wrapper-ERC-20 tokens are prone to this problem as they are compatible with the [ERC-20](./eip-20.md) standard. `rescueERC20` function is implemented to address this problem. 3. Token Converter relies on [ERC-20](./eip-20.md) `approve` & `transferFrom` method of depositing assets. Any related issues must be taken into account. `approve` and `transferFrom` are two separate transactions so it is required to make sure `approval` was successful before relying on `transferFrom`. -4. This is a common practice for UI services to prompt a user to issue unlimited `approval` on any contract that may withdraw tokens from the user. This puts users funds at high risk and therefore not recommended. -5. It is possible to artificially construct a token that will pretend it is a [ERC-20](./eip-20.md) token that implements `approve & transferFrom` but at the same time implements [ERC-223](./eip-223.md) logic of transferring via `transfer` function in its internal logic. It can be possible to create a [ERC-223](./eip-223.md) wrapper for this [ERC-20](./eip-20.md)-[ERC-223](./eip-223.md) hybrid implementation in the Token Converter. This doesn't pose any threat for the workflow of the Token Converter but it must be taken into account that if a token has [ERC-223](./eip-223.md) wrapper in the Token Converter it does not automatically mean the origin is fully compatible with the [ERC-20](./eip-20.md) standard and methods of introspection must be used to determine the origins compatibility with any existing standard. +4. This is a common practice for UI services to prompt a user to issue unlimited `approval` on any contract that may withdraw tokens from the user. This puts users funds at risk and therefore is not recommended. +5. There is no reliable token standard introspection method available that could guarantee that a token implements a particular token standard. It is possible to artificially construct a token that will pretend it is a [ERC-20](./eip-20.md) token that implements `approve & transferFrom` but at the same time implements [ERC-223](./eip-223.md) logic of transferring via `transfer` function. It can be possible to create a [ERC-223](./eip-223.md) wrapper for this [ERC-20](./eip-20.md)-[ERC-223](./eip-223.md) hybrid implementation in the Token Converter. This doesn't pose any threat for the workflow of the Token Converter itself but it must be taken into account that if a token has [ERC-223](./eip-223.md) wrapper in the Token Converter it does not automatically mean the origin is fully compatible with the [ERC-20](./eip-20.md) standard and methods of introspection must be used to determine the origins compatibility with any existing standard. +6. Token Converter does not verify the standard of a provided token when it is asked to create a wrapper for it due to the lack of reliable standard introspection method. It is possible to call `createERC20Wrapper` function and provide an address of an existing [ERC-20](./eip-20.md) token. The Token Converter will successfully create a [ERC-20](./eip-20.md) wrapper for that [ERC-20](./eip-20.md) original token. It is also possible to create a [ERC-223](./eip-223.md) wrapper for that exact original [ERC-20](./eip-20.md) token. This doesn't pose any threat to the workflow of the Converter but it must be taken into account that any token regardless of it's original standard may have up to two wrappers created by the Converter, one for each standard. Any wrapper token must have exactly one origin. It is not possible to create a wrapper for a wrapper. +7. The Token Converter only holds the original tokens that were deposited during the conversion process and it assumes that tokens do not decay over time and the token balance of the Converter does not decrease on its own. If some token implements burning logic or decaying supply and it may impact the balance of the Converter then the Converter must not be used to deploy an alternative version of that token as it will not be able to guarantee that there is enough tokens for the conversion at any time. ## Copyright From eeeeb5f7f1d5d09e31dea16e3870d078b13e2ccf Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Sun, 29 Sep 2024 03:38:51 +0200 Subject: [PATCH 72/79] Add ERC: Wrapping of bubbled up reverts Merged by EIP-Bot. --- ERCS/erc-7751.md | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 ERCS/erc-7751.md diff --git a/ERCS/erc-7751.md b/ERCS/erc-7751.md new file mode 100644 index 0000000000..ac91a16651 --- /dev/null +++ b/ERCS/erc-7751.md @@ -0,0 +1,143 @@ +--- +eip: 7751 +title: Wrapping of bubbled up reverts +description: Handling bubbled up reverts using custom errors with additional context +author: Daniel Gretzke (@gretzke), Sara Reynolds (@snreynolds), Alice Henshaw (@hensha256), Marko Veniger , Hadrien Croubois (@Amxx) +discussions-to: https://ethereum-magicians.org/t/erc-7751-wrapping-of-bubbled-up-reverts/20740 +status: Draft +type: Standards Track +category: ERC +created: 2024-08-06 +--- + +## Abstract + +This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using custom errors. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The custom errors should follow the naming structure `Wrap__` followed by a descriptive name and allow an arbitrary number of parameters, with the first being the address of the called contract and the second being the raw bytes of the bubbled up revert. + +## Motivation + +Currently, when a smart contract calls another and the called contract reverts, the revert reason is usually bubbled up and thrown as is. This can make it more difficult to tell which context the error came from. By standardizing the use of custom errors with additional context, more meaningful and informative revert reasons can be provided. This will improve the debugging experience and make it easier for developers and infrastructure providers like Etherscan to display accurate stack traces. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +1. **Custom Error Naming Convention:** + - Custom errors that bubble up reverts MUST be prefixed with `Wrap__`. + - Example: `Wrap__ERC20TransferFailed`. +2. **Parameters:** + - The first parameter MUST be the address of the called contract that reverted. + - The second parameter MUST be the raw bytes of the bubbled up revert. + - Additional parameters MAY be included to provide context. + - Example: `Wrap__ERC20TransferFailed(address token, bytes reason, address recipient)`. + +If no additional parameters are defined and a generic call reverts, the custom error `Wrap__SubcontextReverted(address, bytes)` SHOULD be thrown to ensure a consistent signature. + +## Rationale + +By including the called contract, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general. + +## Backwards Compatibility + +This ERC does not introduce any backwards incompatibilities. Existing contracts can adopt this standard incrementally. + +## Test Cases + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +contract Token { + mapping(address => uint256) public balanceOf; + + event Transfer(address indexed sender, address indexed recipient, uint amount); + + function transfer(address to, uint256 amount) external returns (bool) { + require(balanceOf[msg.sender] >= amount, "insufficient balance"); + balanceOf[msg.sender] -= amount; + balanceOf[to] += amount; + emit Transfer(msg.sender, to, amount); + return true; + } +} + +contract Vault { + Token token; + + error Wrap__ERC20TransferFailed(address token, bytes reason, address recipient); + + constructor(Token token_) { + token = token_; + } + + function withdraw(address to, uint256 amount) external { + // logic + try token.transfer(to, amount) {} catch (bytes memory error) { + revert Wrap__ERC20TransferFailed(address(token), error, to); + } + } +} + +contract Router { + Vault vault; + + error Wrap__SubcontextReverted(address target, bytes reason); + + constructor(Vault vault_) { + vault = vault_; + } + + function withdraw(uint256 amount) external { + // logic + try vault.withdraw(msg.sender, amount) {} catch (bytes memory error) { + revert Wrap__SubcontextReverted(address(vault), error); + } + } +} + +contract Test { + function test_BubbledNestedReverts(uint256 amount) external { + Token token = new Token(); + Vault vault = new Vault(token); + Router router = new Router(vault); + + try router.withdraw(amount) {} catch (bytes memory thrownError) { + bytes memory expectedError = abi.encodeWithSelector( + Router.Wrap__SubcontextReverted.selector, address(vault), abi.encodeWithSelector( + Vault.Wrap__ERC20TransferFailed.selector, + address(token), + abi.encodeWithSignature("Error(string)", "insufficient balance"), + address(this) + ) + ); + assert(keccak256(thrownError) == keccak256(expectedError)); + } + } +} +``` + +## Reference Implementation + +When catching a revert from a called contract, the calling contract should revert with a custom error following the above conventions. + +```solidity +contract Foo { + error Wrap__SubcontextReverted(address target, bytes reason); + + function foo(address to, bytes memory data) external { + // logic + (bool success, bytes memory returnData) = to.call(data); + if (!success) { + revert Wrap__SubcontextReverted(to, returnData); + } + } +} +``` + +## Security Considerations + +This EIP does not introduce new security risks. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 3cd06e80e25b968ef03248fbf56f090a726c7dc2 Mon Sep 17 00:00:00 2001 From: "drCathieSo.eth" Date: Tue, 1 Oct 2024 22:04:55 +0800 Subject: [PATCH 73/79] Update ERC-7007: Move to Final Merged by EIP-Bot. --- ERCS/erc-7007.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7007.md b/ERCS/erc-7007.md index caac5be17b..ddf6a83c22 100644 --- a/ERCS/erc-7007.md +++ b/ERCS/erc-7007.md @@ -4,8 +4,7 @@ title: Verifiable AI-Generated Content Token description: An ERC-721 extension for verifiable AI-generated content tokens using Zero-Knowledge and Optimistic Machine Learning techniques author: Cathie So (@socathie), Xiaohang Yu (@xhyumiracle), Conway (@0x1cc), Lee Ting Ting (@tina1998612), Kartin discussions-to: https://ethereum-magicians.org/t/eip-7007-zkml-aigc-nfts-an-erc-721-extension-interface-for-zkml-based-aigc-nfts/14216 -status: Last Call -last-call-deadline: 2024-09-30 +status: Final type: Standards Track category: ERC created: 2023-05-10 @@ -233,4 +232,4 @@ In the opML scenario, it is important to consider that the `aigcData` might chan ## Copyright -Copyright and related rights waived via [CC0](../LICENSE.md). \ No newline at end of file +Copyright and related rights waived via [CC0](../LICENSE.md). From b3be3b6f3536dd0c0bf0932de2ea4655c0fcb762 Mon Sep 17 00:00:00 2001 From: Andreas Freund Date: Tue, 1 Oct 2024 07:06:44 -0700 Subject: [PATCH 74/79] Update ERC-6734: Move to Review (#601) * Move ERC 6734 to Status: Review * Updates based on feedbacl Removed mention of EIP-3220 * updated requires section to remove 3220 --- ERCS/erc-6734.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/ERCS/erc-6734.md b/ERCS/erc-6734.md index bacfe8f19e..f22df1b8fe 100644 --- a/ERCS/erc-6734.md +++ b/ERCS/erc-6734.md @@ -4,11 +4,11 @@ title: L2 Token List description: Token List that ensures the correct identification of tokens from different Layer 1, Layer 2, or Sidechains. author: Kelvin Fichter (@smartcontracts), Andreas Freund (@Therecanbeonlyone1969), Pavel Sinelnikov (@psinelnikov) discussions-to: https://ethereum-magicians.org/t/canonical-token-list-standard-from-the-eea-oasis-community-projects-l2-standards-working-group/13091 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-03-20 -requires: 155, 3220 +requires: 155 --- ## Abstract @@ -133,12 +133,7 @@ The chainId property utilized MUST allow for the requirements of the [EIP-155](. Namely, transaction replay protection on the network that is identified by the chainId property value. Note, that for replay protection to be guaranteed, the chainId should be unique. Ensuring a unique chainId is beyond the scope of this document. -[[R4]](#r4) testability: EIP-155 requires that a transaction hash is derived from the keccak256 hash of the following nine RLP encoded elements `(nonce, gasprice, startgas, to, value, data, chainid, 0, 0)` which can be tested easily with existing cryptographic libraries. EIP-155 further requires that the `v` value of the secp256k1 signature must be set to `{0,1} + CHAIN_ID * 2 + 35` where `{0,1}` is the parity of the `y` value of the curve point for which the signature `r`-value is the `x`-value in the secp256k1 signing process. This requirement is testable with available open-source secp256k1 digital signature suites. Therefore, [[R4]](#r4) is testable. - - **[D2]** -The `chainId` property SHOULD follow [EIP-3220](./eip-3220.md) draft standard. - -[[D2]](#d2) testability: The [EIP-3220](./eip-3220.md) draft standard can be tested because the crosschain id is specified as a concatenation of well-defined strings, and using open source tooling can be used to parse and split a crosschain id, the obtained string segments can be compared against expected string lengths, and context dependent, the values for the strings specified in the standard. Consequently, [[D2]](#d2) is testable. +[[R4]](#r4) testability: EIP-155 requires that a transaction hash is derived from the keccak256 hash of the following nine RLP encoded elements `(nonce, gasprice, startgas, to, value, data, chainid, 0, 0)` which can be tested easily with existing cryptographic libraries. EIP-155 further requires that the `v` value of the secp256k1 signature must be set to `{0,1} + CHAIN_ID * 2 + 35` where `{0,1}` is the parity of the `y` value of the curve point for which the signature `r`-value is the `x`-value in the secp256k1 signing process. This requirement is testable with available open-source secp256k1 digital signature suites. Therefore, [[R4]](#r4) is testable. **[O1]** The `humanReadableTokenSymbol` property MAY be used. @@ -491,10 +486,10 @@ This document defines the conformance levels of a canonical token list as follow * **Level 2:** All MUST and SHOULD requirements are fulfilled by a specific implementation as proven by a test report that proves in an easily understandable manner the implementation's conformance with each requirement based on implementation-specific test-fixtures with implementation-specific test-fixture inputs. * **Level 3:** All MUST, SHOULD, and MAY requirements with conditional MUST or SHOULD requirements are fulfilled by a specific implementation as proven by a test report that proves in an easily understandable manner the implementation's conformance with each requirement based on implementation-specific test-fixtures with implementation-specific test-fixture inputs. - **[D3]** + **[D2]** A claim that a canonical token list implementation conforms to this specification SHOULD describe a testing procedure carried out for each requirement to which conformance is claimed, that justifies the claim with respect to that requirement. -[[D3]](#d3) testability: Since each of the non-conformance-target requirements in this documents is testable, so must be the totality of the requirements in this document. Therefore, conformance tests for all requirements can exist, and can be described as required in [[D3]](#d3). +[[D2]](#d2) testability: Since each of the non-conformance-target requirements in this documents is testable, so must be the totality of the requirements in this document. Therefore, conformance tests for all requirements can exist, and can be described as required in [[D2]](#d2). **[R5]** A claim that a canonical token list implementation conforms to this specification at **Level 2** or higher MUST describe the testing procedure carried out for each requirement at **Level 2** or higher, that justifies the claim to that requirement. From 33ff9823e15cb81a0e0880b7d36b7d4fbafa73b9 Mon Sep 17 00:00:00 2001 From: Riley Date: Tue, 1 Oct 2024 10:14:48 -0400 Subject: [PATCH 75/79] Update ERC-6909: Move to Review Merged by EIP-Bot. --- ERCS/erc-6909.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-6909.md b/ERCS/erc-6909.md index ea343004ee..63d566397f 100644 --- a/ERCS/erc-6909.md +++ b/ERCS/erc-6909.md @@ -4,7 +4,7 @@ title: Minimal Multi-Token Interface description: A minimal specification for managing multiple tokens by their id in a single contract. author: JT Riley (@jtriley-eth), Dillon (@d1ll0n), Sara (@snreynolds), Vectorized (@Vectorized), Neodaoist (@neodaoist) discussions-to: https://ethereum-magicians.org/t/eip-6909-multi-token-standard/13891 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-04-19 From a9ea794a79e1852b7b5d847b44b694cd5a99270e Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Fri, 4 Oct 2024 00:22:49 +0200 Subject: [PATCH 76/79] Update ERC-7751: Update custom error and add security considerations Merged by EIP-Bot. --- ERCS/erc-7751.md | 51 +++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/ERCS/erc-7751.md b/ERCS/erc-7751.md index ac91a16651..d12ad7670e 100644 --- a/ERCS/erc-7751.md +++ b/ERCS/erc-7751.md @@ -12,7 +12,7 @@ created: 2024-08-06 ## Abstract -This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using custom errors. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The custom errors should follow the naming structure `Wrap__` followed by a descriptive name and allow an arbitrary number of parameters, with the first being the address of the called contract and the second being the raw bytes of the bubbled up revert. +This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using a dedicated custom error. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The `WrappedError` custom error should wrap reverts from called contracts and provide a consistent interface for parsing and handling reverts in tools like Etherscan or Tenderly. ## Motivation @@ -22,20 +22,22 @@ Currently, when a smart contract calls another and the called contract reverts, The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -1. **Custom Error Naming Convention:** - - Custom errors that bubble up reverts MUST be prefixed with `Wrap__`. - - Example: `Wrap__ERC20TransferFailed`. -2. **Parameters:** - - The first parameter MUST be the address of the called contract that reverted. - - The second parameter MUST be the raw bytes of the bubbled up revert. - - Additional parameters MAY be included to provide context. - - Example: `Wrap__ERC20TransferFailed(address token, bytes reason, address recipient)`. +In order to wrap a revert, a contract MUST revert with the following error that corresponds to the following signature `0x90bfb865`: -If no additional parameters are defined and a generic call reverts, the custom error `Wrap__SubcontextReverted(address, bytes)` SHOULD be thrown to ensure a consistent signature. +```solidity +error WrappedError(address target, bytes4 selector, bytes reason, bytes details); +``` + +Where: + +- `target` is the address of the called contract that reverted. +- `selector` is the selector of the called function that reverted. If the call was an ETH transfer without any data, the selector MUST be `bytes4(0)` +- `reason` is the raw bytes of the revert reason. +- `details` is optional additional context about the revert. In cases where no additional context is needed, the `details` bytes can be empty. In cases with additional context, the `details` bytes MUST be an ABI encoded custom error declared on the contract that emits the `WrappedError` error. ## Rationale -By including the called contract, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general. +By including the called contract and function, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general. ## Backwards Compatibility @@ -64,7 +66,9 @@ contract Token { contract Vault { Token token; - error Wrap__ERC20TransferFailed(address token, bytes reason, address recipient); + error WrappedError(address target, bytes4 selector, bytes reason, bytes details); + error ERC20TransferFailed(address recipient); + constructor(Token token_) { token = token_; @@ -73,7 +77,7 @@ contract Vault { function withdraw(address to, uint256 amount) external { // logic try token.transfer(to, amount) {} catch (bytes memory error) { - revert Wrap__ERC20TransferFailed(address(token), error, to); + revert WrappedError(address(token), token.transfer.selector, error, abi.encodeWithSelector(ERC20TransferFailed.selector, to)); } } } @@ -81,7 +85,7 @@ contract Vault { contract Router { Vault vault; - error Wrap__SubcontextReverted(address target, bytes reason); + error WrappedError(address target, bytes4 selector, bytes reason, bytes details); constructor(Vault vault_) { vault = vault_; @@ -90,7 +94,7 @@ contract Router { function withdraw(uint256 amount) external { // logic try vault.withdraw(msg.sender, amount) {} catch (bytes memory error) { - revert Wrap__SubcontextReverted(address(vault), error); + revert WrappedError(address(vault), vault.withdraw.selector, error, ""); } } } @@ -103,12 +107,13 @@ contract Test { try router.withdraw(amount) {} catch (bytes memory thrownError) { bytes memory expectedError = abi.encodeWithSelector( - Router.Wrap__SubcontextReverted.selector, address(vault), abi.encodeWithSelector( - Vault.Wrap__ERC20TransferFailed.selector, + Router.WrappedError.selector, address(vault), vault.withdraw.selector, abi.encodeWithSelector( + Vault.WrappedError.selector, address(token), + token.transfer.selector, abi.encodeWithSignature("Error(string)", "insufficient balance"), - address(this) - ) + abi.encodeWithSelector(Vault.ERC20TransferFailed.selector, address(this)) + ), "" ); assert(keccak256(thrownError) == keccak256(expectedError)); } @@ -122,13 +127,15 @@ When catching a revert from a called contract, the calling contract should rever ```solidity contract Foo { - error Wrap__SubcontextReverted(address target, bytes reason); + + error WrappedError(address target, bytes4 selector, bytes reason, bytes details); + error MyCustomError(uint256 x); function foo(address to, bytes memory data) external { // logic (bool success, bytes memory returnData) = to.call(data); if (!success) { - revert Wrap__SubcontextReverted(to, returnData); + revert WrappedError(to, bytes4(data), returnData, abi.encodeWithSelector(MyCustomError.selector, 42)); } } } @@ -136,7 +143,7 @@ contract Foo { ## Security Considerations -This EIP does not introduce new security risks. +Smart contracts could either drop or purposefully suppress the bubbled up reverts along the revert chain. Additionally, smart contracts may also lie or incorrectly report the wrapped reverts, so the information is not guaranteed to be accurate. ## Copyright From 610506a71c36bed49dde9339d5c77e884df4ddbc Mon Sep 17 00:00:00 2001 From: filmakarov Date: Fri, 4 Oct 2024 18:09:00 +0300 Subject: [PATCH 77/79] Update ERC-7579: executeUserOp + multitype module onInstall/onUninstall Merged by EIP-Bot. --- ERCS/erc-7579.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ERCS/erc-7579.md b/ERCS/erc-7579.md index 2f3542e23c..8730fe2276 100644 --- a/ERCS/erc-7579.md +++ b/ERCS/erc-7579.md @@ -91,6 +91,13 @@ The account MAY also implement the following function in accordance with ERC-433 function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external; ``` +If an account chooses to implement `executeUserOp`, this method SHOULD ensure the account executes `userOp.calldata` except 4 most significant bytes, which are reserved for `executeUserOp.selector` as per ERC-4337. Thus the `userOp.callData[4:]` should represent the calldata for a valid call to the account. It is RECOMMENDED that the account executes a `delegatecall` in order to preserve the original `msg.sender` to the account. + +Example: +``` +(bool success, bytes memory innerCallRet) = address(this).delegatecall(userOp.callData[4:]); +``` + The execution mode is a `bytes32` value that is structured as follows: - callType (1 byte): `0x00` for a single `call`, `0x01` for a batch `call`, `0xfe` for `staticcall` and `0xff` for `delegatecall` @@ -223,6 +230,9 @@ If the smart account has a fallback handler installed, it: - MUST route to fallback handlers based on the function selector of the calldata - MAY implement authorization control, which SHOULD be done via hooks +If the account adds features via fallback, these should be considered the same as if the account was implementing those features natively. +ERC-165 support (see below) is one example of such an approach. Note, that it is only RECOMMENDED to implement view functions via fallback where this can lead to greater extensibility. It is NOT RECOMMENDED to implement core account logic via a fallback. + #### ERC-165 Smart accounts MUST implement ERC-165. However, for every interface function that reverts instead of implementing the functionality, the smart account MUST return `false` for the corresponding interface id. @@ -268,6 +278,17 @@ interface IModule { } ``` +Note: A single module that is of multiple types MAY decide to pass `moduleTypeId` inside `data` to `onInstall` and/or `onUninstall` methods, so those methods are able to properly handle installation/uninstallation for various types. +Example: +```solidity +// Module.sol +function onInstall(bytes calldata data) external { + // ... + (uint256 moduleTypeId, bytes memory otherData) = abi.decode(data, (uint256, bytes)); + // ... +} +``` + #### Validators Validators MUST implement the `IModule` and the `IValidator` interface and have module type id: `1`. From 1526cbae597a40a9192f14c35c907811b91a5bf1 Mon Sep 17 00:00:00 2001 From: Vidor <1101164+V1d0r@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:32:53 +0100 Subject: [PATCH 78/79] Update ERC-7578: Update getter and setter methods naming Merged by EIP-Bot. --- ERCS/erc-7578.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ERCS/erc-7578.md b/ERCS/erc-7578.md index 9acb4fbb37..b4a237483f 100644 --- a/ERCS/erc-7578.md +++ b/ERCS/erc-7578.md @@ -104,7 +104,7 @@ interface IERC7578 { * @dev Does NOT revert if token doesn't exist * @param tokenId The token ID of the minted token */ - function getProperties(uint256 tokenId) external view returns (Properties memory properties); + function getPropertiesOf(uint256 tokenId) external view returns (Properties memory properties); } ``` @@ -112,7 +112,7 @@ When `properties` are set, the `PropertiesSet(uint256 indexed tokenId, Propertie When `properties` are removed, the `PropertiesRemoved(uint256 indexed tokenId)` event is emitted. -The `getProperties(uint256 tokenId)` function MUST return the unique `properties` of a token. If the ERC-721 token is burned or has no properties set, it SHOULD return an empty `Properties` struct. +The `getPropertiesOf(uint256 tokenId)` function MUST return the unique `properties` of a token. If the ERC-721 token is burned or has no properties set, it SHOULD return an empty `Properties` struct. ## Rationale @@ -158,7 +158,7 @@ contract ERC7578 is ERC721, IERC7578 { /** * @inheritdoc IERC7578 */ - function getProperties(uint256 tokenId) public view override returns (Properties memory properties) { + function getPropertiesOf(uint256 tokenId) public view override returns (Properties memory properties) { properties = _properties[tokenId]; } @@ -172,7 +172,7 @@ contract ERC7578 is ERC721, IERC7578 { * * Emits a {PropertiesSet} event */ - function _setProperties(uint256 tokenId, Properties calldata properties) internal { + function _setPropertiesOf(uint256 tokenId, Properties calldata properties) internal { _properties[tokenId] = Properties({ tokenIssuer: properties.tokenIssuer, assetHolder: properties.assetHolder, @@ -194,7 +194,7 @@ contract ERC7578 is ERC721, IERC7578 { * * Emits a {PropertiesRemoved} event */ - function _removeProperties(uint256 tokenId) internal { + function _removePropertiesOf(uint256 tokenId) internal { delete _properties[tokenId]; emit PropertiesRemoved(tokenId); } @@ -207,7 +207,7 @@ contract ERC7578 is ERC721, IERC7578 { function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { address from = _ownerOf(tokenId); if (to == address(0)) { - _removeProperties(tokenId); + _removePropertiesOf(tokenId); } else if (from == address(0)) { if (bytes(_properties[tokenId].tokenIssuer).length == 0) revert PropertiesUninitialized(); } @@ -219,7 +219,7 @@ contract ERC7578 is ERC721, IERC7578 { ## Security Considerations -To ensure the authenticity of a token's properties, the `_setProperties()` method should only be called inside a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the token. +To ensure the authenticity of a token's properties, the `_setPropertiesOf()` method should only be called inside a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the token. ## Copyright From 3173a488e7d4da604ae137d38ab3bbfd9ee4064a Mon Sep 17 00:00:00 2001 From: sshmatrix Date: Fri, 11 Oct 2024 22:50:40 +0530 Subject: [PATCH 79/79] Make ERC-7700 Image Optimsations Merged by EIP-Bot. --- assets/erc-7700/fonts/Licenses/Rajdhani.txt | 93 + assets/erc-7700/fonts/Rajdhani.woff2 | 2365 +++++++++++++++++++ assets/erc-7700/images/Database.svg | 291 ++- assets/erc-7700/images/Keygen.svg | 710 +++--- assets/erc-7700/images/L1.svg | 288 +-- assets/erc-7700/images/L2.svg | 188 +- assets/erc-7700/images/Schema.svg | 1736 +++++++------- 7 files changed, 4093 insertions(+), 1578 deletions(-) create mode 100644 assets/erc-7700/fonts/Licenses/Rajdhani.txt create mode 100644 assets/erc-7700/fonts/Rajdhani.woff2 diff --git a/assets/erc-7700/fonts/Licenses/Rajdhani.txt b/assets/erc-7700/fonts/Licenses/Rajdhani.txt new file mode 100644 index 0000000000..fa88d37258 --- /dev/null +++ b/assets/erc-7700/fonts/Licenses/Rajdhani.txt @@ -0,0 +1,93 @@ +Copyright (c) 2009, Indian Type Foundry + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/assets/erc-7700/fonts/Rajdhani.woff2 b/assets/erc-7700/fonts/Rajdhani.woff2 new file mode 100644 index 0000000000..5545c74460 --- /dev/null +++ b/assets/erc-7700/fonts/Rajdhani.woff2 @@ -0,0 +1,2365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ERCs/assets/erc-7694/fonts/Rajdhani.woff2 at solanaHandler · namesys-eth/ERCs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ Skip to content + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + +
+ Open in github.dev + Open in a new github.dev tab + Open in codespace + + + + + + + + + + + + + + + + + + +

Latest commit

 

History

History
99.4 KB

Rajdhani.woff2

File metadata and controls

99.4 KB
+
+ + + + +
+ +
+ +
+
+ +
+ +
+

Footer

+ + + + +
+
+ + + + + © 2024 GitHub, Inc. + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + diff --git a/assets/erc-7700/images/Database.svg b/assets/erc-7700/images/Database.svg index 0da7511326..ee11cff923 100644 --- a/assets/erc-7700/images/Database.svg +++ b/assets/erc-7700/images/Database.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="538.99292mm" - height="246.26625mm" - viewBox="0 0 538.99292 246.26626" + width="539.02795mm" + height="246.15076mm" + viewBox="0 0 539.02795 246.15077" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="Database.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="Database.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -206,132 +216,105 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-33.411763,-64.921999)"> - - HTTP POST [ + + HTTP POST [signer] [signature] [approval] - [[callData] - - - setValue(calldata) - - - - L1 - - - - DB - + + L1 + + DB CONTRACT 1 + x="452.81824" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 1 revert StorageRoutedToDatabase(gatewayURL) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">revert StorageRoutedToDatabase[gatewayURL] response + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">response - - - + CLIENT - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">CLIENT DATABASE + x="530.03149" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">DATABASE + + setValue[calldata] + diff --git a/assets/erc-7700/images/Keygen.svg b/assets/erc-7700/images/Keygen.svg index 232ab77238..ae3da761be 100644 --- a/assets/erc-7700/images/Keygen.svg +++ b/assets/erc-7700/images/Keygen.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="354.92731mm" - height="284.96518mm" - viewBox="0 0 354.92731 284.96518" + width="355.14566mm" + height="284.86801mm" + viewBox="0 0 355.14566 284.86801" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="Keygen.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="Keygen.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -200,7 +210,14 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-26.391586,-23.472401)"> + transform="translate(-26.319521,-23.400335)"> + keypairdecode + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:start;text-anchor:start;stroke:#ff4f00;stroke-width:0.502;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="301.8284" + y="147.56477" + id="tspan1159">KEYPAIR CAIP-10 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.624383;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="-175.52129" + y="108.35208" + id="tspan2163-0-2-6-4-3-7">CAIP-10 pubkey PUBKEY[address] + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:start;text-anchor:start;stroke:#ff5500;stroke-width:0.429033;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="-165.38974" + y="99.295135" + id="tspan2447">[ADDRESS] MESSAGE signature + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.438444;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="191.58209" + y="254.40422" + id="tspan2163-0-2-6-4-3-2">SIGNATURE salt + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.345378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="241.88663" + y="227.65532" + id="tspan2163-0-2-6-4-3-2-2">SALT wallet WALLETkeypair + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:start;text-anchor:start;fill:#0079ff;fill-opacity:1;stroke:#0079ff;stroke-width:0.433269;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="71.353035" + y="104.03593" + id="tspan1102">KEYPAIR inputINPUT key + style="font-size:4.95802px;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.337097;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="tspan3283"> KEY hashkey + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.359125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="282.19537" + y="154.02812" + id="tspan2163-0-2-6-4-3-2-2-0">HASHKEY - - - - USERNAME - - + + USERNAME - - - - password - - + + PASSWORD @@ -716,58 +705,52 @@ id="path1062-2-9-3-6" sodipodi:nodetypes="cccc" /> signerSIGNERkeys - - - CAIP-02 - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ff4f00;fill-opacity:1;stroke:#ff4f00;stroke-width:0.516629;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="366.21487" + y="134.32416" + id="tspan1153">KEYS + + CAIP-02 otherOTHERkeys + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.516629;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="366.21487" + y="175.10515" + id="tspan1149">KEYS @@ -918,22 +901,22 @@ transform="matrix(0.27231888,0,0,0.27231888,213.85157,218.02482)" /> hkdf + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.594683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="351.99957" + y="270.04156" + id="tspan2163-0-2-6-4-3-6-1">HKDF @@ -967,46 +950,30 @@ style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /> - - sha-SHA-256 - 256 - sign + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.594683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="350.82336" + y="285.1387" + id="tspan2163-0-2-6-4-3-6-1-7">SIGN @@ -1015,28 +982,28 @@ + transform="matrix(0.07723047,0,0,0.07723047,316.7695,193.49336)" + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:4.39179;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:8.79949;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + style="fill:#8c8c8c;fill-opacity:1;stroke:#ffffff;stroke-width:8.79949;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - - - - PROTOCOL - - + + PROTOCOL - - PBKDfPBKDF2 - 2 - @@ -1191,29 +1130,25 @@ style="fill:#ff4f00;fill-opacity:1;stroke:#ff4f00;stroke-width:18.1111;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - - - spice - + + SPICE - - - - pepper - - + + PEPPER + DECODE diff --git a/assets/erc-7700/images/L1.svg b/assets/erc-7700/images/L1.svg index 5b96abeecd..8899f9aa57 100644 --- a/assets/erc-7700/images/L1.svg +++ b/assets/erc-7700/images/L1.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="538.99292mm" - height="246.12524mm" - viewBox="0 0 538.99292 246.12525" + width="538.9527mm" + height="246.08514mm" + viewBox="0 0 538.9527 246.08515" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="L1.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="L1.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -206,58 +216,72 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-33.411763,-65.062998)"> + transform="translate(-33.582213,-65.062996)"> + + + + + + Execute on Mainnet [Execute on Mainnet [contract] [callData] setValue(calldata) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.26869px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">setValue(calldata) - - @@ -268,74 +292,65 @@ sodipodi:nodetypes="ccccccccccc" /> L1 - - - - L1 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">L1 + + style="font-size:12.8702px;line-height:1.25;font-family:Palatino;-inkscape-font-specification:Palatino;font-variant-ligatures:none;text-align:center;letter-spacing:0.264583px;text-anchor:middle;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.771;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="513.16644" + y="112.60666" + id="text1098-9-0" + transform="scale(1.0134682,0.98671079)">L1 CONTRACT 1 + x="452.81824" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 1 CONTRACT 2 + x="527.39014" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 2 @@ -345,189 +360,190 @@ id="path1225-8" sodipodi:nodetypes="cc" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> - - revert revert StorageRoutedToL1(contract) - + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> response + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">response CLIENT + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CLIENT + diff --git a/assets/erc-7700/images/L2.svg b/assets/erc-7700/images/L2.svg index 992e67b6a6..bc2e12bc71 100644 --- a/assets/erc-7700/images/L2.svg +++ b/assets/erc-7700/images/L2.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="538.99292mm" - height="246.12524mm" - viewBox="0 0 538.99292 246.12525" + width="538.23016mm" + height="245.64159mm" + viewBox="0 0 538.23016 245.64159" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="L2.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/keygen.png" + inkscape:export-filename="L2.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -206,52 +216,57 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-33.411763,-65.062998)"> + transform="translate(-33.411762,-65.062996)"> + Execute on L2 [Execute on L2 [contract] [callData] setValue(calldata) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.26869px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">setValue[calldata] @@ -269,7 +284,7 @@ sodipodi:nodetypes="ccccccccccc" /> L1 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">L1 + style="fill:none;stroke:#ff5300;stroke-opacity:1"> L2 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">L2 CONTRACT 1 + x="452.81824" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 1 CONTRACT 2 + x="527.39014" + y="91.454376" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.325693;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">CONTRACT 2 @@ -346,169 +361,168 @@ id="path1225-8" sodipodi:nodetypes="cc" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> revert StorageRoutedToL2(chainId, contract) + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">revert StorageRoutedToL2[chainId, contract] + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1"> + style="fill:#0085ff;fill-opacity:1;stroke:#0085ff;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1"> + style="fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-opacity:1" /> response + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ff5300;fill-opacity:1;stroke:#ff5300;stroke-width:0.257131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">response @@ -519,7 +533,7 @@ sodipodi:nodetypes="ccccccc" /> CLIENT + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.771;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;">CLIENT diff --git a/assets/erc-7700/images/Schema.svg b/assets/erc-7700/images/Schema.svg index e78b204601..5e54cf63a4 100644 --- a/assets/erc-7700/images/Schema.svg +++ b/assets/erc-7700/images/Schema.svg @@ -8,14 +8,14 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="420.71497mm" - height="251.75276mm" - viewBox="0 0 420.71498 251.75276" + width="420.40274mm" + height="251.61508mm" + viewBox="0 0 420.40275 251.61508" version="1.1" id="svg6" inkscape:version="1.0.2 (e86c8708, 2021-01-15)" sodipodi:docname="Schema.svg" - inkscape:export-filename="/Users/sshmatrix/Idee/sshmatrix/Buidl/namesys-eth/namesys-ccip-write/images/schematic.png" + inkscape:export-filename="Schema.png" inkscape:export-xdpi="200" inkscape:export-ydpi="200"> + @@ -258,21 +265,33 @@ id="layer1" transform="translate(-7.6321621,-18.227982)"> + + - ns1 - ns2 - ns3 - @@ -459,20 +432,6 @@ id="g1654-5" transform="matrix(0,-1,-1,0,416.6934,364.09144)" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - OffchainLookup(sender urls[] calldata callback() extradata ) - callback() - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;stroke-width:0.264583" /> - extradata - - - - - - - - - Read - return - gateway - result - - - EIP-3668 - EIP-7700 - L2 - database - IPNS - ar - SOLANA - IPFS - IPNS - storage - ns1 - ns2 - ns3 + style="fill:#ffffff;fill-opacity:0.141129;stroke:#ffffff;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> - L2 - IPFS - DATABASE - ARWEAVE - SOLANA - - - - + + - STORE - gateway - json-rpc - http - ipfs2 - ar-io - arns - arns @@ -1481,13 +818,795 @@
+ + + + EIP-7694 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OffchainLookup[sender urls[] calldata callback() extradata ] + callback[] + + extradata + + + + + + + + + READ + RETURN + GATEWAY + result + + + EIP-3668 + + L2 + DATABASE + SOLANA + STORAGE + NS1 + NS2 + NS3 + NS1 + NS2 + NS3 + IPNS + AR + IPFS + IPNS + ARNS + JSON-RPC + HTTP + API + JSON-RPC + IPFS2 + AR-IO + + + + + EIP-7694 + L 2 + DATABASE + SOLANA + STORE + GATEWAY + METADATA + IPFS + ARWEAVE + transform="translate(-12.561236,-26.217714)"> + transform="matrix(0.41454246,0,0,0.45705146,254.00403,204.65357)" + style="opacity:0.495177;fill:#ffffff;fill-opacity:1;stroke-width:0.999361;stroke-miterlimit:4;stroke-dasharray:none"> requires CID/keygen + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.01859px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.334075;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="418.63412" + y="266.1683" + id="tspan2163-0-2-6-4-3-0-7-4-0-1-8-6-8-2">REQUIRES KEYGEN + style="opacity:0.495177;fill:#ffffff;fill-opacity:1;stroke-width:0.339802" /> requires signature + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.89777px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.324031;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="374.89169" + y="257.35449" + id="tspan2163-0-2-6-4-3-0-7-4-0-1-8-6-8-2-2">REQUIRES SIGNATURE requires REQUIRES $ payment + dy="0.3754442">$ PAYMENT API - metadata - - - + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.50059px;font-family:Rajdhani;-inkscape-font-specification:Rajdhani;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.46084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="220.93579" + y="159.33699" + id="tspan2163-0-2-6-4-3-0-7-4-0-1-8-6-1-4-7-0-1-9">ARNS