diff --git a/README.md b/README.md index ae1c72e1..49ea2a21 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,13 @@ -# Aragon OSX Plugin Template [![Hardhat][hardhat-badge]][hardhat] [![License: AGPL v3][license-badge]][license] +# Multisig Plugin [![Hardhat][hardhat-badge]][hardhat] [![License: AGPL v3][license-badge]][license] [hardhat]: https://hardhat.org/ [hardhat-badge]: https://img.shields.io/badge/Built%20with-Hardhat-FFDB1C.svg [license]: https://opensource.org/licenses/AGPL-v3 [license-badge]: https://img.shields.io/badge/License-AGPL_v3-blue.svg -## Quickstart - -After [creating a new repository from this template](https://github.com/new?template_name=osx-plugin-template-hardhat&template_owner=aragon), cloning, and opening it in your IDE, run - -```sh -yarn install && cd packages/contracts && yarn install && yarn build && yarn typechain -``` - -Meanwhile, create an `.env` file from the `.env.example` file and put in the API keys for the services that you want to use. -You can now develop a plugin by changing the `src/MyPlugin.sol` and `src/MyPluginSetup.sol` files. You can directly import contracts from [Aragon OSx](https://github.com/aragon/osx) as well as OpenZeppelin's [openzeppelin-contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) and [openzeppelin-contracts-upgradeable](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable) that are already set up for you. - -```sol -// SPDX-License-Identifier: AGPL-3.0-or-later -pragma solidity ^0.8.17; - -import {IDAO, PluginUUPSUpgradeable} from "@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol"; -import {SafeCastUpgradeable} from '@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol'; - -contract MyPlugin is PluginUUPSUpgradeable { - //... -}; -``` - -The initial `MyPlugin` and `MyPluginSetup` example comes with unit test, integration test, and test helpers in the `package/contracts/test` folder that you can reuse. - -To build and test your contracts, run - -```sh -yarn clean && yarn build && yarn test -``` - ## Project -The root folder of the repo includes three subfolders: +The root folder of the repo includes two subfolders: ```markdown . @@ -202,15 +171,29 @@ Deploy the contracts to the local Hardhat Network (being forked from the network yarn deploy --tags CreateRepo,NewVersion ``` -This will create a plugin repo and publish the the first version (`v1.1`) of your plugin. +This will create a plugin repo and publish the first version (`v1.1`) of your plugin. +By adding the tag `TransferOwnershipToManagmentDao`, the `ROOT_PERMISSION_ID`, `MAINTAINER_PERMISSION_ID`, and +`UPGRADE_REPO_PERMISSION_ID` are granted to the management DAO and revoked from the deployer. +You can do this directly + +```sh +yarn deploy --tags CreateRepo,NewVersion,TransferOwnershipToManagmentDao +``` + +or at a later point by executing + +```sh +yarn deploy --tags TransferOwnershipToManagmentDao +``` -Deploy the contracts to sepolia with +To deploy the contracts to a production network use the `--network` option, for example ```sh -yarn deploy --network sepolia --tags CreateRepo,NewVersion,Verification +yarn deploy --network sepolia --tags CreateRepo,NewVersion,TransferOwnershipToManagmentDao,Verification ``` -This will create a plugin repo, publish the the first version (`v1.1`) of your plugin, and verfiy the contracts on sepolia. +This will create a plugin repo, publish the first version (`v1.1`) of your plugin, transfer permissions to the +management DAO, and lastly verfiy the contracts on sepolia. If you want to deploy a new version of your plugin afterwards (e.g., `1.2`), simply change the `VERSION` entry in the `packages/contracts/plugin-settings.ts` file and use @@ -218,6 +201,8 @@ If you want to deploy a new version of your plugin afterwards (e.g., `1.2`), sim yarn deploy --network sepolia --tags NewVersion,Verification ``` +Note, that if the deploying account doesn't own the repo anymore, this will create a `createVersionProposalData-sepolia.json` containing the data for a management DAO signer to create a proposal publishing a new version. + Note, that if you include the `CreateRepo` tag after you've created your plugin repo already, this part of the script will be skipped. #### Upgrading Your Plugin Repository @@ -237,6 +222,8 @@ yarn deploy --network sepolia --tags UpgradeRepo This will upgrade your plugin repo to the latest Aragon OSx protocol version implementation, which might include new features and security updates. **For this to work, make sure that you are using the latest version of [this repository](https://github.com/aragon/osx-plugin-template-hardhat) in your fork.** +Note, that if the deploying account doesn't own the repo anymore, this will create a `upgradeRepoProposalData-sepolia.json` containing the data for a management DAO signer to create a proposal upgrading the repo. + ## Subgraph ### Installing diff --git a/package.json b/package.json index 26e1cb04..26d74775 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@aragon/osx-plugin-template", + "name": "@aragon/multisig-plugin", "description": "A template to fork from when developing an Aragon OSx plugin", "version": "0.0.1-alpha.1", "license": "AGPL-3.0-or-later", diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md new file mode 100644 index 00000000..2f604829 --- /dev/null +++ b/packages/contracts/CHANGELOG.md @@ -0,0 +1,17 @@ +# Multisig Plugin + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to the [Aragon OSx Plugin Versioning Convention](https://devs.aragon.org/docs/osx/how-to-guides/plugin-development/publication/versioning). + +## v1.3 + +### Added + +- Copied files from [aragon/osx commit 1130df](https://github.com/aragon/osx/commit/1130dfce94fd294c4341e91a8f3faccc54cf43b7) + +### Changed + +- Used `ProxyLib` from `osx-commons-contracts` for the minimal proxy deployment in `MultisigSetup`. +- Hard-coded the `bytes32 internal constant EXECUTE_PERMISSION_ID` constant in `MultisigSetup` until it is available in `PermissionLib`. diff --git a/packages/contracts/deploy/20_new_version/21_setup.ts b/packages/contracts/deploy/20_new_version/21_setup.ts index 7ef97b63..a52a1b28 100644 --- a/packages/contracts/deploy/20_new_version/21_setup.ts +++ b/packages/contracts/deploy/20_new_version/21_setup.ts @@ -21,7 +21,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { }); console.log( - `Deployed '${PLUGIN_SETUP_CONTRACT_NAME}' contract at '${res.address}'` + `Deployed contract '${PLUGIN_SETUP_CONTRACT_NAME}' at ${res.address}.` ); }; diff --git a/packages/contracts/deploy/20_new_version/22_setup_conclude.ts b/packages/contracts/deploy/20_new_version/22_setup_conclude.ts index 1b514b68..e4d3dc39 100644 --- a/packages/contracts/deploy/20_new_version/22_setup_conclude.ts +++ b/packages/contracts/deploy/20_new_version/22_setup_conclude.ts @@ -1,5 +1,5 @@ import {PLUGIN_SETUP_CONTRACT_NAME} from '../../plugin-settings'; -import {MyPluginSetup__factory, MyPlugin__factory} from '../../typechain'; +import {MultisigSetup__factory, Multisig__factory} from '../../typechain'; import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; import path from 'path'; @@ -17,12 +17,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get the plugin setup address const setupDeployment = await deployments.get(PLUGIN_SETUP_CONTRACT_NAME); - const setup = MyPluginSetup__factory.connect( + const setup = MultisigSetup__factory.connect( setupDeployment.address, deployer ); // Get the plugin implementation address - const implementation = MyPlugin__factory.connect( + const implementation = Multisig__factory.connect( await setup.implementation(), deployer ); diff --git a/packages/contracts/deploy/20_new_version/23_publish.ts b/packages/contracts/deploy/20_new_version/23_publish.ts index ea146b9b..0dbba782 100644 --- a/packages/contracts/deploy/20_new_version/23_publish.ts +++ b/packages/contracts/deploy/20_new_version/23_publish.ts @@ -1,5 +1,6 @@ import { METADATA, + PLUGIN_CONTRACT_NAME, PLUGIN_REPO_ENS_SUBDOMAIN_NAME, PLUGIN_SETUP_CONTRACT_NAME, VERSION, @@ -7,6 +8,8 @@ import { import { findPluginRepo, getPastVersionCreatedEvents, + impersonatedManagementDaoSigner, + isLocal, pluginEnsDomain, } from '../../utils/helpers'; import { @@ -14,6 +17,7 @@ import { toHex, uploadToIPFS, } from '@aragon/osx-commons-sdk'; +import {writeFile} from 'fs/promises'; import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; import path from 'path'; @@ -77,25 +81,42 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); } - // Create Version + if (setup == undefined || setup?.receipt == undefined) { + throw Error('setup deployment unavailable'); + } + + const isDeployerMaintainer = await pluginRepo.isGranted( + pluginRepo.address, + deployer.address, + PLUGIN_REPO_PERMISSIONS.MAINTAINER_PERMISSION_ID, + [] + ); + + // If this is a local deployment and the deployer doesn't have `MAINTAINER_PERMISSION_ID` permission + // we impersonate the management DAO for integration testing purposes. + const signer = + isDeployerMaintainer || !isLocal(hre) + ? deployer + : await impersonatedManagementDaoSigner(hre); + + // Check if the signer has the permission to maintain the plugin repo if ( - await pluginRepo.callStatic.isGranted( + await pluginRepo.isGranted( pluginRepo.address, - deployer.address, + signer.address, PLUGIN_REPO_PERMISSIONS.MAINTAINER_PERMISSION_ID, [] ) ) { - const tx = await pluginRepo.createVersion( - VERSION.release, - setup.address, - toHex(buildMetadataURI), - toHex(releaseMetadataURI) - ); - - if (setup == undefined || setup?.receipt == undefined) { - throw Error('setup deployment unavailable'); - } + // Create the new version + const tx = await pluginRepo + .connect(signer) + .createVersion( + VERSION.release, + setup.address, + toHex(buildMetadataURI), + toHex(releaseMetadataURI) + ); await tx.wait(); @@ -110,8 +131,31 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { `Published ${PLUGIN_SETUP_CONTRACT_NAME} at ${setup.address} in PluginRepo ${PLUGIN_REPO_ENS_SUBDOMAIN_NAME} at ${pluginRepo.address}.` ); } else { - throw Error( - `The new version cannot be published because the deployer ('${deployer.address}') is lacking the ${PLUGIN_REPO_PERMISSIONS.MAINTAINER_PERMISSION_ID} permission on repo (${pluginRepo.address}).` + // The deployer does not have `MAINTAINER_PERMISSION_ID` permission and we are not deploying to a production network, + // so we write the data into a file for a management DAO member to create a proposal from it. + const data = { + proposalTitle: `Publish '${PLUGIN_CONTRACT_NAME}' plugin v${VERSION.release}.${VERSION.build}`, + proposalSummary: `Publishes v${VERSION.release}.${VERSION.build} of the '${PLUGIN_CONTRACT_NAME}' plugin in the '${ensDomain}' plugin repo.`, + proposalDescription: `Publishes the '${PLUGIN_SETUP_CONTRACT_NAME}' deployed at '${setup.address}' + as v${VERSION.release}.${VERSION.build} in the '${ensDomain}' plugin repo at '${pluginRepo.address}', + with release metadata '${releaseMetadataURI}' and (immutable) build metadata '${buildMetadataURI}'.`, + actions: [ + { + to: pluginRepo.address, + createVersion: { + _release: VERSION.release, + _pluginSetup: setup.address, + _buildMetadata: toHex(buildMetadataURI), + _releaseMetadata: toHex(releaseMetadataURI), + }, + }, + ], + }; + + const path = `./createVersionProposalData-${hre.network.name}.json`; + await writeFile(path, JSON.stringify(data, null, 2)); + console.log( + `Saved data to '${path}'. Use this to create a proposal on the managing DAO calling the 'createVersion' function on the ${ensDomain} plugin repo deployed at ${pluginRepo.address}.` ); } }; diff --git a/packages/contracts/deploy/30_upgrade_repo/31_upgrade_repo.ts b/packages/contracts/deploy/30_upgrade_repo/31_upgrade_repo.ts index f862559c..7ca2b168 100644 --- a/packages/contracts/deploy/30_upgrade_repo/31_upgrade_repo.ts +++ b/packages/contracts/deploy/30_upgrade_repo/31_upgrade_repo.ts @@ -1,4 +1,9 @@ -import {findPluginRepo, getProductionNetworkName} from '../../utils/helpers'; +import { + findPluginRepo, + getProductionNetworkName, + impersonatedManagementDaoSigner, + isLocal, +} from '../../utils/helpers'; import { getLatestNetworkDeployment, getNetworkNameByAlias, @@ -9,6 +14,7 @@ import { } from '@aragon/osx-commons-sdk'; import {PluginRepo__factory} from '@aragon/osx-ethers'; import {BytesLike} from 'ethers'; +import {writeFile} from 'fs/promises'; import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; import path from 'path'; @@ -74,11 +80,25 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { */ const initializeFromCalldata: BytesLike = []; - // Check if deployer has the permission to upgrade the plugin repo + const isDeployerUpgrader = await pluginRepo.isGranted( + pluginRepo.address, + deployer.address, + PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, + [] + ); + + // If this is a local deployment and the deployer doesn't have `UPGRADE_REPO_PERMISSION_ID` permission + // we impersonate the management DAO for integration testing purposes. + const signer = + isDeployerUpgrader || !isLocal(hre) + ? deployer + : await impersonatedManagementDaoSigner(hre); + + // Check if the signer has the permission to upgrade the plugin repo if ( await pluginRepo.isGranted( pluginRepo.address, - deployer.address, + signer.address, PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, [] ) @@ -94,9 +114,35 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await pluginRepo.upgradeTo(latestPluginRepoImplementation.address); } } else { - throw Error( - `The new version cannot be published because the deployer ('${deployer.address}') - is lacking the ${PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID} permission.` + // The deployer does not have `UPGRADE_REPO_PERMISSION_ID` permission and we are not deploying to a production network, + // so we write the data into a file for a management DAO member to create a proposal from it. + const upgradeAction = + initializeFromCalldata.length === 0 + ? { + to: pluginRepo.address, + upgradeTo: { + NewImplementation: latestPluginRepoImplementation.address, + }, + } + : { + to: pluginRepo.address, + upgradeToAndCall: { + NewImplementation: latestPluginRepoImplementation.address, + Data: initializeFromCalldata, + PayableAmount: 0, + }, + }; + const data = { + proposalTitle: `Upgrade the '${ensDomain}' plugin repo`, + proposalSummary: `Upgrades '${ensDomain}' plugin repo at '${pluginRepo.address}',' plugin in the '${ensDomain}' plugin repo.`, + proposalDescription: `TODO: Describe the changes to the 'PluginRepo' implementation.`, + actions: [upgradeAction], + }; + + const path = `./upgradeRepoProposalData-${hre.network.name}.json`; + await writeFile(path, JSON.stringify(data, null, 2)); + console.log( + `Saved data to '${path}'. Use this to create a proposal on the managing DAO calling the 'upgradeTo' or 'upgradeToAndCall' function on the ${ensDomain} plugin repo deployed at ${pluginRepo.address}.` ); } }; diff --git a/packages/contracts/deploy/40_conclude/41_transfer_ownership.ts b/packages/contracts/deploy/40_conclude/41_transfer_ownership.ts new file mode 100644 index 00000000..935fb83a --- /dev/null +++ b/packages/contracts/deploy/40_conclude/41_transfer_ownership.ts @@ -0,0 +1,111 @@ +import {findPluginRepo, getManagementDao} from '../../utils/helpers'; +import { + DAO_PERMISSIONS, + Operation, + PERMISSION_MANAGER_FLAGS, + PLUGIN_REPO_PERMISSIONS, +} from '@aragon/osx-commons-sdk'; +import {DAOStructs} from '@aragon/osx-ethers'; +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import path from 'path'; + +/** + * Creates a plugin repo under Aragon's ENS base domain with subdomain requested in the `./plugin-settings.ts` file. + * @param {HardhatRuntimeEnvironment} hre + */ +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + // Get PluginRepo + const {pluginRepo, ensDomain} = await findPluginRepo(hre); + if (pluginRepo === null) { + throw `PluginRepo '${ensDomain}' does not exist yet.`; + } + + // Get the management DAO address + const managementDao = await getManagementDao(hre); + const [deployer] = await hre.ethers.getSigners(); + + console.log( + `Transferring ownership of the '${ensDomain}' plugin repo at '${pluginRepo.address}' from the deployer '${deployer.address}' to the management DAO at '${managementDao.address}'...` + ); + + const permissions: DAOStructs.MultiTargetPermissionStruct[] = [ + // Grant to the management DAO + { + operation: Operation.Grant, + where: pluginRepo.address, + who: managementDao.address, + condition: PERMISSION_MANAGER_FLAGS.NO_CONDITION, + permissionId: PLUGIN_REPO_PERMISSIONS.MAINTAINER_PERMISSION_ID, + }, + { + operation: Operation.Grant, + where: pluginRepo.address, + who: managementDao.address, + condition: PERMISSION_MANAGER_FLAGS.NO_CONDITION, + permissionId: PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, + }, + { + operation: Operation.Grant, + where: pluginRepo.address, + who: managementDao.address, + condition: PERMISSION_MANAGER_FLAGS.NO_CONDITION, + permissionId: DAO_PERMISSIONS.ROOT_PERMISSION_ID, + }, + // Revoke from deployer + { + operation: Operation.Revoke, + where: pluginRepo.address, + who: deployer.address, + condition: PERMISSION_MANAGER_FLAGS.NO_CONDITION, + permissionId: PLUGIN_REPO_PERMISSIONS.MAINTAINER_PERMISSION_ID, + }, + { + operation: Operation.Revoke, + where: pluginRepo.address, + who: deployer.address, + condition: PERMISSION_MANAGER_FLAGS.NO_CONDITION, + permissionId: PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, + }, + { + operation: Operation.Revoke, + where: pluginRepo.address, + who: deployer.address, + condition: PERMISSION_MANAGER_FLAGS.NO_CONDITION, + permissionId: DAO_PERMISSIONS.ROOT_PERMISSION_ID, + }, + ]; + + await pluginRepo.connect(deployer).applyMultiTargetPermissions(permissions); +}; + +export default func; +func.tags = ['TransferOwnershipToManagmentDao']; + +/** + * Skips the transfer of ownership if it has already been transferred to the management DAO + * @param {HardhatRuntimeEnvironment} hre + */ +func.skip = async (hre: HardhatRuntimeEnvironment) => { + console.log(`\n🏗️ ${path.basename(__filename)}:`); + + const {pluginRepo, ensDomain} = await findPluginRepo(hre); + if (pluginRepo === null) { + throw `PluginRepo '${ensDomain}' does not exist yet.`; + } + const managementDao = await getManagementDao(hre); + + const mgmtDaoHasRootPerm = await pluginRepo.isGranted( + pluginRepo.address, + managementDao.address, + DAO_PERMISSIONS.ROOT_PERMISSION_ID, + [] + ); + + if (mgmtDaoHasRootPerm) + console.log( + `The ownership of the plugin repo '${ensDomain}' has already been transferred to the management DAO. Skipping...` + ); + + return mgmtDaoHasRootPerm; +}; diff --git a/packages/contracts/deploy/40_conclude/41_conclude.ts b/packages/contracts/deploy/40_conclude/42_info.ts similarity index 100% rename from packages/contracts/deploy/40_conclude/41_conclude.ts rename to packages/contracts/deploy/40_conclude/42_info.ts diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index 3608e253..749b7d34 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -104,8 +104,8 @@ const config: HardhatUserConfig = { hardhat: { throwOnTransactionFailures: true, throwOnCallFailures: true, - blockGasLimit: BigNumber.from(10).pow(6).mul(30).toNumber(), // 30 million, really high to test some things that are only possible with a higher block gas limit - gasPrice: BigNumber.from(10).pow(9).mul(150).toNumber(), // 150 gwei + blockGasLimit: BigNumber.from(10).pow(6).mul(300).toNumber(), // 300 million, really high to test some things that are only possible with a higher block gas limit + gasPrice: BigNumber.from(10).pow(9).mul(300).toNumber(), // 300 gwei accounts: getHardhatNetworkAccountsConfig( Object.keys(namedAccounts).length ), diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 4587efee..53244bb6 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,5 +1,5 @@ { - "name": "@aragon/osx-plugin-template-contracts", + "name": "@aragon/multisig-plugin-contracts", "version": "1.0.0", "license": "AGPL-3.0-or-later", "scripts": { @@ -20,9 +20,10 @@ }, "devDependencies": { "@aragon/osx-commons-configs": "0.1.0", - "@aragon/osx-ethers": "1.4.0-alpha.0", "@aragon/osx-commons-sdk": "0.0.1-alpha.5", - "@aragon/osx-artifacts": "1.3.1", + "@aragon/osx-ethers": "1.4.0-alpha.0", + "@aragon/osx-v1.0.0": "npm:@aragon/osx@1.0.1", + "@aragon/osx-v1.3.0": "npm:@aragon/osx@1.3.0", "@ethersproject/abi": "^5.7.0", "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", diff --git a/packages/contracts/plugin-settings.ts b/packages/contracts/plugin-settings.ts index f19ee5bf..18e3ce5a 100644 --- a/packages/contracts/plugin-settings.ts +++ b/packages/contracts/plugin-settings.ts @@ -2,16 +2,15 @@ import buildMetadata from './src/build-metadata.json'; import releaseMetadata from './src/release-metadata.json'; import {VersionTag} from '@aragon/osx-commons-sdk'; -export const PLUGIN_CONTRACT_NAME = 'MyPlugin'; // This must match the filename `packages/contracts/src/MyPlugin.sol` and the contract name `MyPlugin` within. -export const PLUGIN_SETUP_CONTRACT_NAME = 'MyPluginSetup'; // This must match the filename `packages/contracts/src/MyPluginSetup.sol` and the contract name `MyPluginSetup` within. -export const PLUGIN_REPO_ENS_SUBDOMAIN_NAME = 'my'; // This will result in the ENS domain name 'my.plugin.dao.eth' +export const PLUGIN_CONTRACT_NAME = 'Multisig'; +export const PLUGIN_SETUP_CONTRACT_NAME = 'MultisigSetup'; +export const PLUGIN_REPO_ENS_SUBDOMAIN_NAME = 'multisig'; // 'multisig.plugin.dao.eth' export const VERSION: VersionTag = { release: 1, // Increment this number ONLY if breaking/incompatible changes were made. Updates between releases are NOT possible. - build: 1, // Increment this number if non-breaking/compatible changes were made. Updates to newer builds are possible. + build: 3, // Increment this number if non-breaking/compatible changes were made. Updates to newer builds are possible. }; -/* DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING */ export const METADATA = { build: buildMetadata, release: releaseMetadata, diff --git a/packages/contracts/src/IMultisig.sol b/packages/contracts/src/IMultisig.sol new file mode 100644 index 00000000..ee143932 --- /dev/null +++ b/packages/contracts/src/IMultisig.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.8; + +/// @title IMultisig +/// @author Aragon Association - 2023 +/// @notice An interface for an on-chain multisig governance plugin in which a proposal passes +/// if X out of Y approvals are met. +/// @custom:security-contact sirt@aragon.org +interface IMultisig { + /// @notice Adds new members to the address list. Previously, it checks if the new address + /// list length would be greater than `type(uint16).max`, the maximal number of approvals. + /// @param _members The addresses of the members to be added. + function addAddresses(address[] calldata _members) external; + + /// @notice Removes existing members from the address list. Previously, it checks if the + /// new address list length is at least as long as the minimum approvals parameter requires. + /// Note that `minApprovals` is must be at least 1 so the address list cannot become empty. + /// @param _members The addresses of the members to be removed. + function removeAddresses(address[] calldata _members) external; + + /// @notice Approves and, optionally, executes the proposal. + /// @param _proposalId The ID of the proposal. + /// @param _tryExecution If `true`, execution is tried after the approval cast. + /// The call does not revert if execution is not possible. + function approve(uint256 _proposalId, bool _tryExecution) external; + + /// @notice Checks if an account can participate on a proposal vote. This can be because the vote + /// - was executed, or + /// - the voter is not listed. + /// @param _proposalId The proposal Id. + /// @param _account The address of the user to check. + /// @return Returns true if the account is allowed to vote. + /// @dev The function assumes the queried proposal exists. + function canApprove(uint256 _proposalId, address _account) external view returns (bool); + + /// @notice Checks if a proposal can be executed. + /// @param _proposalId The ID of the proposal to be checked. + /// @return True if the proposal can be executed, false otherwise. + function canExecute(uint256 _proposalId) external view returns (bool); + + /// @notice Returns whether the account has approved the proposal. Note, that this does not check + // if the account is listed. + /// @param _proposalId The ID of the proposal. + /// @param _account The account address to be checked. + /// @return The vote option cast by a voter for a certain proposal. + function hasApproved(uint256 _proposalId, address _account) external view returns (bool); + + /// @notice Executes a proposal. + /// @param _proposalId The ID of the proposal to be executed. + function execute(uint256 _proposalId) external; +} diff --git a/packages/contracts/src/Multisig.sol b/packages/contracts/src/Multisig.sol new file mode 100644 index 00000000..c941cf2e --- /dev/null +++ b/packages/contracts/src/Multisig.sol @@ -0,0 +1,479 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.8; + +/* solhint-disable max-line-length */ +import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; + +import {IMembership} from "@aragon/osx-commons-contracts/src/plugin/extensions/membership/IMembership.sol"; +import {Addresslist} from "@aragon/osx-commons-contracts/src/plugin/extensions/governance/Addresslist.sol"; +import {ProposalUpgradeable} from "@aragon/osx-commons-contracts/src/plugin/extensions/proposal/ProposalUpgradeable.sol"; +import {PluginUUPSUpgradeable} from "@aragon/osx-commons-contracts/src/plugin/PluginUUPSUpgradeable.sol"; +import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol"; + +import {IMultisig} from "./IMultisig.sol"; + +/* solhint-enable max-line-length */ + +/// @title Multisig +/// @author Aragon Association - 2022-2023 +/// @notice The on-chain multisig governance plugin in which a proposal passes if X out of Y approvals are met. +/// @dev v1.3 (Release 1, Build 3) +/// @custom:security-contact sirt@aragon.org +contract Multisig is + IMultisig, + IMembership, + PluginUUPSUpgradeable, + ProposalUpgradeable, + Addresslist +{ + using SafeCastUpgradeable for uint256; + + /// @notice A container for proposal-related information. + /// @param executed Whether the proposal is executed or not. + /// @param approvals The number of approvals casted. + /// @param parameters The proposal-specific approve settings at the time of the proposal creation. + /// @param approvers The approves casted by the approvers. + /// @param actions The actions to be executed when the proposal passes. + /// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. + /// If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. + /// A failure map value of 0 requires every action to not revert. + struct Proposal { + bool executed; + uint16 approvals; + ProposalParameters parameters; + mapping(address => bool) approvers; + IDAO.Action[] actions; + uint256 allowFailureMap; + } + + /// @notice A container for the proposal parameters. + /// @param minApprovals The number of approvals required. + /// @param snapshotBlock The number of the block prior to the proposal creation. + /// @param startDate The timestamp when the proposal starts. + /// @param endDate The timestamp when the proposal expires. + struct ProposalParameters { + uint16 minApprovals; + uint64 snapshotBlock; + uint64 startDate; + uint64 endDate; + } + + /// @notice A container for the plugin settings. + /// @param onlyListed Whether only listed addresses can create a proposal or not. + /// @param minApprovals The minimal number of approvals required for a proposal to pass. + struct MultisigSettings { + bool onlyListed; + uint16 minApprovals; + } + + /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. + bytes4 internal constant MULTISIG_INTERFACE_ID = + this.initialize.selector ^ + this.updateMultisigSettings.selector ^ + this.createProposal.selector ^ + this.getProposal.selector; + + /// @notice The ID of the permission required to call the `addAddresses` and `removeAddresses` functions. + bytes32 public constant UPDATE_MULTISIG_SETTINGS_PERMISSION_ID = + keccak256("UPDATE_MULTISIG_SETTINGS_PERMISSION"); + + /// @notice A mapping between proposal IDs and proposal information. + // solhint-disable-next-line named-parameters-mapping + mapping(uint256 => Proposal) internal proposals; + + /// @notice The current plugin settings. + MultisigSettings public multisigSettings; + + /// @notice Keeps track at which block number the multisig settings have been changed the last time. + /// @dev This variable prevents a proposal from being created in the same block in which the multisig + /// settings change. + uint64 public lastMultisigSettingsChange; + + /// @notice Thrown when a sender is not allowed to create a proposal. + /// @param sender The sender address. + error ProposalCreationForbidden(address sender); + + /// @notice Thrown if an approver is not allowed to cast an approve. This can be because the proposal + /// - is not open, + /// - was executed, or + /// - the approver is not on the address list + /// @param proposalId The ID of the proposal. + /// @param sender The address of the sender. + error ApprovalCastForbidden(uint256 proposalId, address sender); + + /// @notice Thrown if the proposal execution is forbidden. + /// @param proposalId The ID of the proposal. + error ProposalExecutionForbidden(uint256 proposalId); + + /// @notice Thrown if the minimal approvals value is out of bounds (less than 1 or greater than the number of + /// members in the address list). + /// @param limit The maximal value. + /// @param actual The actual value. + error MinApprovalsOutOfBounds(uint16 limit, uint16 actual); + + /// @notice Thrown if the address list length is out of bounds. + /// @param limit The limit value. + /// @param actual The actual value. + error AddresslistLengthOutOfBounds(uint16 limit, uint256 actual); + + /// @notice Thrown if a date is out of bounds. + /// @param limit The limit value. + /// @param actual The actual value. + error DateOutOfBounds(uint64 limit, uint64 actual); + + /// @notice Emitted when a proposal is approve by an approver. + /// @param proposalId The ID of the proposal. + /// @param approver The approver casting the approve. + event Approved(uint256 indexed proposalId, address indexed approver); + + /// @notice Emitted when the plugin settings are set. + /// @param onlyListed Whether only listed addresses can create a proposal. + /// @param minApprovals The minimum amount of approvals needed to pass a proposal. + event MultisigSettingsUpdated(bool onlyListed, uint16 indexed minApprovals); + + /// @notice Initializes Release 1, Build 2. + /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + /// @param _dao The IDAO interface of the associated DAO. + /// @param _members The addresses of the initial members to be added. + /// @param _multisigSettings The multisig settings. + function initialize( + IDAO _dao, + address[] calldata _members, + MultisigSettings calldata _multisigSettings + ) external initializer { + __PluginUUPSUpgradeable_init(_dao); + + if (_members.length > type(uint16).max) { + revert AddresslistLengthOutOfBounds({limit: type(uint16).max, actual: _members.length}); + } + + _addAddresses(_members); + emit MembersAdded({members: _members}); + + _updateMultisigSettings(_multisigSettings); + } + + /// @notice Checks if this or the parent contract supports an interface by its ID. + /// @param _interfaceId The ID of the interface. + /// @return Returns `true` if the interface is supported. + function supportsInterface( + bytes4 _interfaceId + ) public view virtual override(PluginUUPSUpgradeable, ProposalUpgradeable) returns (bool) { + return + _interfaceId == MULTISIG_INTERFACE_ID || + _interfaceId == type(IMultisig).interfaceId || + _interfaceId == type(Addresslist).interfaceId || + _interfaceId == type(IMembership).interfaceId || + super.supportsInterface(_interfaceId); + } + + /// @inheritdoc IMultisig + function addAddresses( + address[] calldata _members + ) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) { + uint256 newAddresslistLength = addresslistLength() + _members.length; + + // Check if the new address list length would be greater than `type(uint16).max`, the maximal number of + // approvals. + if (newAddresslistLength > type(uint16).max) { + revert AddresslistLengthOutOfBounds({ + limit: type(uint16).max, + actual: newAddresslistLength + }); + } + + _addAddresses(_members); + + emit MembersAdded({members: _members}); + } + + /// @inheritdoc IMultisig + function removeAddresses( + address[] calldata _members + ) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) { + uint16 newAddresslistLength = uint16(addresslistLength() - _members.length); + + // Check if the new address list length would become less than the current minimum number of approvals required. + if (newAddresslistLength < multisigSettings.minApprovals) { + revert MinApprovalsOutOfBounds({ + limit: newAddresslistLength, + actual: multisigSettings.minApprovals + }); + } + + _removeAddresses(_members); + + emit MembersRemoved({members: _members}); + } + + /// @notice Updates the plugin settings. + /// @param _multisigSettings The new settings. + function updateMultisigSettings( + MultisigSettings calldata _multisigSettings + ) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) { + _updateMultisigSettings(_multisigSettings); + } + + /// @notice Creates a new multisig proposal. + /// @param _metadata The metadata of the proposal. + /// @param _actions The actions that will be executed after the proposal passes. + /// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. + /// If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. + /// A failure map value of 0 requires every action to not revert. + /// @param _approveProposal If `true`, the sender will approve the proposal. + /// @param _tryExecution If `true`, execution is tried after the vote cast. The call does not revert if early + /// execution is not possible. + /// @param _startDate The start date of the proposal. + /// @param _endDate The end date of the proposal. + /// @return proposalId The ID of the proposal. + // solhint-disable-next-line code-complexity + function createProposal( + bytes calldata _metadata, + IDAO.Action[] calldata _actions, + uint256 _allowFailureMap, + bool _approveProposal, + bool _tryExecution, + uint64 _startDate, + uint64 _endDate + ) external returns (uint256 proposalId) { + if (multisigSettings.onlyListed && !isListed(_msgSender())) { + revert ProposalCreationForbidden(_msgSender()); + } + + uint64 snapshotBlock; + unchecked { + // The snapshot block must be mined already to protect the transaction against backrunning transactions + // causing census changes. + snapshotBlock = block.number.toUint64() - 1; + } + + // Revert if the settings have been changed in the same block as this proposal should be created in. + // This prevents a malicious party from voting with previous addresses and the new settings. + if (lastMultisigSettingsChange > snapshotBlock) { + revert ProposalCreationForbidden(_msgSender()); + } + + if (_startDate == 0) { + _startDate = block.timestamp.toUint64(); + } else if (_startDate < block.timestamp.toUint64()) { + revert DateOutOfBounds({limit: block.timestamp.toUint64(), actual: _startDate}); + } + + if (_endDate < _startDate) { + revert DateOutOfBounds({limit: _startDate, actual: _endDate}); + } + + proposalId = _createProposal({ + _creator: _msgSender(), + _metadata: _metadata, + _startDate: _startDate, + _endDate: _endDate, + _actions: _actions, + _allowFailureMap: _allowFailureMap + }); + + // Create the proposal + Proposal storage proposal_ = proposals[proposalId]; + + proposal_.parameters.snapshotBlock = snapshotBlock; + proposal_.parameters.startDate = _startDate; + proposal_.parameters.endDate = _endDate; + proposal_.parameters.minApprovals = multisigSettings.minApprovals; + + // Reduce costs + if (_allowFailureMap != 0) { + proposal_.allowFailureMap = _allowFailureMap; + } + + for (uint256 i; i < _actions.length; ) { + proposal_.actions.push(_actions[i]); + unchecked { + ++i; + } + } + + if (_approveProposal) { + approve(proposalId, _tryExecution); + } + } + + /// @inheritdoc IMultisig + function approve(uint256 _proposalId, bool _tryExecution) public { + address approver = _msgSender(); + if (!_canApprove(_proposalId, approver)) { + revert ApprovalCastForbidden(_proposalId, approver); + } + + Proposal storage proposal_ = proposals[_proposalId]; + + // As the list can never become more than type(uint16).max(due to addAddresses check) + // It's safe to use unchecked as it would never overflow. + unchecked { + proposal_.approvals += 1; + } + + proposal_.approvers[approver] = true; + + emit Approved({proposalId: _proposalId, approver: approver}); + + if (_tryExecution && _canExecute(_proposalId)) { + _execute(_proposalId); + } + } + + /// @inheritdoc IMultisig + function canApprove(uint256 _proposalId, address _account) external view returns (bool) { + return _canApprove(_proposalId, _account); + } + + /// @inheritdoc IMultisig + function canExecute(uint256 _proposalId) external view returns (bool) { + return _canExecute(_proposalId); + } + + /// @notice Returns all information for a proposal vote by its ID. + /// @param _proposalId The ID of the proposal. + /// @return executed Whether the proposal is executed or not. + /// @return approvals The number of approvals casted. + /// @return parameters The parameters of the proposal vote. + /// @return actions The actions to be executed in the associated DAO after the proposal has passed. + /// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. + /// If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. + /// A failure map value of 0 requires every action to not revert. + function getProposal( + uint256 _proposalId + ) + public + view + returns ( + bool executed, + uint16 approvals, + ProposalParameters memory parameters, + IDAO.Action[] memory actions, + uint256 allowFailureMap + ) + { + Proposal storage proposal_ = proposals[_proposalId]; + + executed = proposal_.executed; + approvals = proposal_.approvals; + parameters = proposal_.parameters; + actions = proposal_.actions; + allowFailureMap = proposal_.allowFailureMap; + } + + /// @inheritdoc IMultisig + function hasApproved(uint256 _proposalId, address _account) public view returns (bool) { + return proposals[_proposalId].approvers[_account]; + } + + /// @inheritdoc IMultisig + function execute(uint256 _proposalId) public { + if (!_canExecute(_proposalId)) { + revert ProposalExecutionForbidden(_proposalId); + } + + _execute(_proposalId); + } + + /// @inheritdoc IMembership + function isMember(address _account) external view returns (bool) { + return isListed(_account); + } + + /// @notice Internal function to execute a vote. It assumes the queried proposal exists. + /// @param _proposalId The ID of the proposal. + function _execute(uint256 _proposalId) internal { + Proposal storage proposal_ = proposals[_proposalId]; + + proposal_.executed = true; + + _executeProposal( + dao(), + _proposalId, + proposals[_proposalId].actions, + proposals[_proposalId].allowFailureMap + ); + } + + /// @notice Internal function to check if an account can approve. It assumes the queried proposal exists. + /// @param _proposalId The ID of the proposal. + /// @param _account The account to check. + /// @return Returns `true` if the given account can approve on a certain proposal and `false` otherwise. + function _canApprove(uint256 _proposalId, address _account) internal view returns (bool) { + Proposal storage proposal_ = proposals[_proposalId]; + + if (!_isProposalOpen(proposal_)) { + // The proposal was executed already + return false; + } + + if (!isListedAtBlock(_account, proposal_.parameters.snapshotBlock)) { + // The approver has no voting power. + return false; + } + + if (proposal_.approvers[_account]) { + // The approver has already approved + return false; + } + + return true; + } + + /// @notice Internal function to check if a proposal can be executed. It assumes the queried proposal exists. + /// @param _proposalId The ID of the proposal. + /// @return Returns `true` if the proposal can be executed and `false` otherwise. + function _canExecute(uint256 _proposalId) internal view returns (bool) { + Proposal storage proposal_ = proposals[_proposalId]; + + // Verify that the proposal has not been executed or expired. + if (!_isProposalOpen(proposal_)) { + return false; + } + + return proposal_.approvals >= proposal_.parameters.minApprovals; + } + + /// @notice Internal function to check if a proposal vote is still open. + /// @param proposal_ The proposal struct. + /// @return True if the proposal vote is open, false otherwise. + function _isProposalOpen(Proposal storage proposal_) internal view returns (bool) { + uint64 currentTimestamp64 = block.timestamp.toUint64(); + return + !proposal_.executed && + proposal_.parameters.startDate <= currentTimestamp64 && + proposal_.parameters.endDate >= currentTimestamp64; + } + + /// @notice Internal function to update the plugin settings. + /// @param _multisigSettings The new settings. + function _updateMultisigSettings(MultisigSettings calldata _multisigSettings) internal { + uint16 addresslistLength_ = uint16(addresslistLength()); + + if (_multisigSettings.minApprovals > addresslistLength_) { + revert MinApprovalsOutOfBounds({ + limit: addresslistLength_, + actual: _multisigSettings.minApprovals + }); + } + + if (_multisigSettings.minApprovals < 1) { + revert MinApprovalsOutOfBounds({limit: 1, actual: _multisigSettings.minApprovals}); + } + + multisigSettings = _multisigSettings; + lastMultisigSettingsChange = block.number.toUint64(); + + emit MultisigSettingsUpdated({ + onlyListed: _multisigSettings.onlyListed, + minApprovals: _multisigSettings.minApprovals + }); + } + + /// @dev This empty reserved space is put in place to allow future versions to add new + /// variables without shifting down storage in the inheritance chain. + /// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + uint256[47] private __gap; +} diff --git a/packages/contracts/src/MultisigSetup.sol b/packages/contracts/src/MultisigSetup.sol new file mode 100644 index 00000000..59f36481 --- /dev/null +++ b/packages/contracts/src/MultisigSetup.sol @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.8; + +/* solhint-disable max-line-length */ +import {PermissionLib} from "@aragon/osx-commons-contracts/src/permission/PermissionLib.sol"; +import {IPluginSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/IPluginSetup.sol"; +import {PluginUpgradeableSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/PluginUpgradeableSetup.sol"; +import {ProxyLib} from "@aragon/osx-commons-contracts/src/utils/deployment/ProxyLib.sol"; +import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol"; + +import {Multisig} from "./Multisig.sol"; + +/* solhint-enable max-line-length */ + +/// @title MultisigSetup +/// @author Aragon Association - 2022-2023 +/// @notice The setup contract of the `Multisig` plugin. +/// @dev v1.3 (Release 1, Build 3) +/// @custom:security-contact sirt@aragon.org +contract MultisigSetup is PluginUpgradeableSetup { + using ProxyLib for address; + + // TODO This permission identifier will be moved into a library in task OS-954. + /// @notice The ID of the permission required to call the `execute` function. + bytes32 internal constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); + + /// @notice The contract constructor, that deploys the `Multisig` plugin logic contract. + constructor() PluginUpgradeableSetup(address(new Multisig())) {} + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes calldata _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + // Decode `_data` to extract the params needed for deploying and initializing `Multisig` plugin. + (address[] memory members, Multisig.MultisigSettings memory multisigSettings) = abi.decode( + _data, + (address[], Multisig.MultisigSettings) + ); + + // Deploy and initialize the plugin UUPS proxy. + plugin = IMPLEMENTATION.deployUUPSProxy( + abi.encodeCall(Multisig.initialize, (IDAO(_dao), members, multisigSettings)) + ); + + // Prepare permissions + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](3); + + // Set permissions to be granted. + // Grant the list of permissions of the plugin to the DAO. + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: Multisig(IMPLEMENTATION).UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() + }); + + permissions[1] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: Multisig(IMPLEMENTATION).UPGRADE_PLUGIN_PERMISSION_ID() + }); + + // Grant `EXECUTE_PERMISSION` of the DAO to the plugin. + permissions[2] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: _dao, + who: plugin, + condition: PermissionLib.NO_CONDITION, + permissionId: EXECUTE_PERMISSION_ID + }); + + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + /// @dev Nothing needs to happen for the update. + function prepareUpdate( + address _dao, + uint16 _currentBuild, + SetupPayload calldata _payload + ) + external + pure + override + returns (bytes memory initData, PreparedSetupData memory preparedSetupData) + // solhint-disable-next-line no-empty-blocks + { + + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + // Prepare permissions + permissions = new PermissionLib.MultiTargetPermission[](3); + + // Set permissions to be Revoked. + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _payload.plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: Multisig(IMPLEMENTATION).UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() + }); + + permissions[1] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _payload.plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: Multisig(IMPLEMENTATION).UPGRADE_PLUGIN_PERMISSION_ID() + }); + + permissions[2] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _dao, + who: _payload.plugin, + condition: PermissionLib.NO_CONDITION, + permissionId: EXECUTE_PERMISSION_ID + }); + } +} diff --git a/packages/contracts/src/MyPlugin.sol b/packages/contracts/src/MyPlugin.sol deleted file mode 100644 index ec8739f7..00000000 --- a/packages/contracts/src/MyPlugin.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later -pragma solidity ^0.8.8; - -import {PluginUUPSUpgradeable} from "@aragon/osx-commons-contracts/src/plugin/PluginUUPSUpgradeable.sol"; -import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol"; - -/// @title MyPlugin -/// @dev Release 1, Build 1 -contract MyPlugin is PluginUUPSUpgradeable { - /// @notice The ID of the permission required to call the `storeNumber` function. - bytes32 public constant STORE_PERMISSION_ID = keccak256("STORE_PERMISSION"); - - uint256 public number; // added in build 1 - - /// @notice Emitted when a number is stored. - /// @param number The number. - event NumberStored(uint256 number); - - /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() { - _disableInitializers(); - } - - /// @notice Initializes the plugin when build 1 is installed. - /// @param _number The number to be stored. - function initialize(IDAO _dao, uint256 _number) external initializer { - __PluginUUPSUpgradeable_init(_dao); - number = _number; - - emit NumberStored({number: _number}); - } - - /// @notice Stores a new number to storage. Caller needs STORE_PERMISSION. - /// @param _number The number to be stored. - function storeNumber(uint256 _number) external auth(STORE_PERMISSION_ID) { - number = _number; - - emit NumberStored({number: _number}); - } -} diff --git a/packages/contracts/src/MyPluginSetup.sol b/packages/contracts/src/MyPluginSetup.sol deleted file mode 100644 index 01993a20..00000000 --- a/packages/contracts/src/MyPluginSetup.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity ^0.8.8; - -import {PermissionLib} from "@aragon/osx-commons-contracts/src/permission/PermissionLib.sol"; -import {ProxyLib} from "@aragon/osx-commons-contracts/src/utils/deployment/ProxyLib.sol"; -import {PluginUpgradeableSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/PluginUpgradeableSetup.sol"; -import {IPluginSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/IPluginSetup.sol"; -import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol"; - -import {MyPlugin} from "./MyPlugin.sol"; - -/// @title MyPluginSetup -/// @dev Release 1, Build 1 -contract MyPluginSetup is PluginUpgradeableSetup { - using ProxyLib for address; - - /// @notice Constructs the `PluginUpgradeableSetup` by storing the `MyPlugin` implementation address. - /// @dev The implementation address is used to deploy UUPS proxies referencing it and - /// to verify the plugin on the respective block explorers. - constructor() PluginUpgradeableSetup(address(new MyPlugin())) {} - - /// @notice The ID of the permission required to call the `storeNumber` function. - bytes32 internal constant STORE_PERMISSION_ID = keccak256("STORE_PERMISSION"); - - /// @inheritdoc IPluginSetup - function prepareInstallation( - address _dao, - bytes memory _data - ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { - uint256 number = abi.decode(_data, (uint256)); - - plugin = IMPLEMENTATION.deployUUPSProxy( - abi.encodeCall(MyPlugin.initialize, (IDAO(_dao), number)) - ); - - PermissionLib.MultiTargetPermission[] - memory permissions = new PermissionLib.MultiTargetPermission[](1); - - permissions[0] = PermissionLib.MultiTargetPermission({ - operation: PermissionLib.Operation.Grant, - where: plugin, - who: _dao, - condition: PermissionLib.NO_CONDITION, - permissionId: STORE_PERMISSION_ID - }); - - preparedSetupData.permissions = permissions; - } - - /// @inheritdoc IPluginSetup - /// @dev The default implementation for the initial build 1 that reverts because no earlier build exists. - function prepareUpdate( - address _dao, - uint16 _fromBuild, - SetupPayload calldata _payload - ) external pure virtual returns (bytes memory, PreparedSetupData memory) { - (_dao, _fromBuild, _payload); - revert InvalidUpdatePath({fromBuild: 0, thisBuild: 1}); - } - - /// @inheritdoc IPluginSetup - function prepareUninstallation( - address _dao, - SetupPayload calldata _payload - ) external pure returns (PermissionLib.MultiTargetPermission[] memory permissions) { - permissions = new PermissionLib.MultiTargetPermission[](1); - - permissions[0] = PermissionLib.MultiTargetPermission({ - operation: PermissionLib.Operation.Revoke, - where: _payload.plugin, - who: _dao, - condition: PermissionLib.NO_CONDITION, - permissionId: STORE_PERMISSION_ID - }); - } -} diff --git a/packages/contracts/src/build-metadata.json b/packages/contracts/src/build-metadata.json index ba36b8b4..21182af0 100644 --- a/packages/contracts/src/build-metadata.json +++ b/packages/contracts/src/build-metadata.json @@ -1,21 +1,50 @@ { "ui": {}, - "change": "Initial build.", + "change": "v1.3\n - TODO TODO.", "pluginSetup": { "prepareInstallation": { - "description": "The information required for the installation of build 1.", + "description": "The information required for the installation.", "inputs": [ { - "name": "number", - "type": "uint256", - "internalType": "uint256", - "description": "The initial number to be stored." + "internalType": "address[]", + "name": "members", + "type": "address[]", + "description": "The addresses of the initial members to be added." + }, + { + "components": [ + { + "internalType": "bool", + "name": "onlyListed", + "type": "bool", + "description": "Whether only listed addresses can create a proposal or not." + }, + { + "internalType": "uint16", + "name": "minApprovals", + "type": "uint16", + "description": "The minimal number of approvals required for a proposal to pass." + } + ], + "internalType": "struct Multisig.MultisigSettings", + "name": "multisigSettings", + "type": "tuple", + "description": "The initial multisig settings." } ] }, - "prepareUpdate": {}, + "prepareUpdate": { + "1": { + "description": "No input is required for the update.", + "inputs": [] + }, + "2": { + "description": "No input is required for the update.", + "inputs": [] + } + }, "prepareUninstallation": { - "description": "The information required for the uninstallation of build 1.", + "description": "No input is required for the uninstallation.", "inputs": [] } } diff --git a/packages/contracts/src/mocks/DAOMock.sol b/packages/contracts/src/mocks/DAOMock.sol deleted file mode 100644 index 008fcecf..00000000 --- a/packages/contracts/src/mocks/DAOMock.sol +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity ^0.8.8; - -import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol"; -import {IPermissionCondition} from "@aragon/osx-commons-contracts/src/permission/condition/IPermissionCondition.sol"; -import {PermissionLib} from "@aragon/osx-commons-contracts/src/permission/PermissionLib.sol"; - -contract DAOMock is IDAO { - address internal constant NO_CONDITION = address(0); - - event Granted( - bytes32 indexed permissionId, - address indexed here, - address where, - address indexed who, - address condition - ); - - event Revoked( - bytes32 indexed permissionId, - address indexed here, - address where, - address indexed who - ); - - bool public hasPermissionReturnValueMock; - - function setHasPermissionReturnValueMock(bool _hasPermissionReturnValueMock) external { - hasPermissionReturnValueMock = _hasPermissionReturnValueMock; - } - - function hasPermission( - address _where, - address _who, - bytes32 _permissionId, - bytes memory _data - ) external view override returns (bool) { - (_where, _who, _permissionId, _data); - return hasPermissionReturnValueMock; - } - - function applyMultiTargetPermissions( - PermissionLib.MultiTargetPermission[] calldata _items - ) external { - for (uint256 i; i < _items.length; ) { - PermissionLib.MultiTargetPermission memory item = _items[i]; - - if (item.operation == PermissionLib.Operation.Grant) { - grant({_where: item.where, _who: item.who, _permissionId: item.permissionId}); - } else if (item.operation == PermissionLib.Operation.Revoke) { - revoke({_where: item.where, _who: item.who, _permissionId: item.permissionId}); - } else if (item.operation == PermissionLib.Operation.GrantWithCondition) { - grantWithCondition({ - _where: item.where, - _who: item.who, - _permissionId: item.permissionId, - _condition: IPermissionCondition(item.condition) - }); - } - - unchecked { - ++i; - } - } - } - - function grant(address _where, address _who, bytes32 _permissionId) public { - (_where, _who, _permissionId); - - emit Granted({ - permissionId: _permissionId, - here: msg.sender, - where: _where, - who: _who, - condition: NO_CONDITION - }); - } - - function revoke(address _where, address _who, bytes32 _permissionId) public { - (_where, _who, _permissionId); - - emit Revoked({permissionId: _permissionId, here: msg.sender, where: _where, who: _who}); - } - - function grantWithCondition( - address _where, - address _who, - bytes32 _permissionId, - IPermissionCondition _condition - ) public { - emit Granted({ - permissionId: _permissionId, - here: msg.sender, - where: _where, - who: _who, - condition: address(_condition) - }); - } - - function getTrustedForwarder() public pure override returns (address) { - return address(0); - } - - function setTrustedForwarder(address _trustedForwarder) external pure override { - (_trustedForwarder); - } - - function setMetadata(bytes calldata _metadata) external pure override { - (_metadata); - } - - function execute( - bytes32 callId, - Action[] memory _actions, - uint256 allowFailureMap - ) external override returns (bytes[] memory execResults, uint256 failureMap) { - emit Executed(msg.sender, callId, _actions, allowFailureMap, failureMap, execResults); - } - - function deposit( - address _token, - uint256 _amount, - string calldata _reference - ) external payable override { - (_token, _amount, _reference); - } - - function setSignatureValidator(address _signatureValidator) external pure override { - (_signatureValidator); - } - - function isValidSignature( - bytes32 _hash, - bytes memory _signature - ) external pure override returns (bytes4) { - (_hash, _signature); - return 0x0; - } - - function registerStandardCallback( - bytes4 _interfaceId, - bytes4 _callbackSelector, - bytes4 _magicNumber - ) external pure override { - (_interfaceId, _callbackSelector, _magicNumber); - } -} diff --git a/packages/contracts/src/mocks/Migration.sol b/packages/contracts/src/mocks/Migration.sol new file mode 100644 index 00000000..faac7b6f --- /dev/null +++ b/packages/contracts/src/mocks/Migration.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.8; + +/** + * @title Migration + * + * @dev This file allows importing contracts to obtain compiler artifacts for testing purposes. + * + * After a contract is imported here and the project is compiled, an associated artifact will be + * generated inside artifacts/@aragon/{version-name}/*, + * and TypeChain typings will be generated inside typechain/osx-version/{version-name}/* + * for type-safe interactions with the contract in our tests. + */ + +/* solhint-disable no-unused-import */ +/* solhint-disable max-line-length */ +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +// Regression Testing +import {Multisig as Multisig_v1_1} from "@aragon/osx-v1.0.0/plugins/governance/multisig/Multisig.sol"; +import {Multisig as Multisig_v1_2} from "@aragon/osx-v1.3.0/plugins/governance/multisig/Multisig.sol"; + +import {ProxyFactory} from "@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory.sol"; + +/* solhint-enable max-line-length */ +/* solhint-enable no-unused-import */ diff --git a/packages/contracts/src/release-metadata.json b/packages/contracts/src/release-metadata.json index a99ed49b..bd15c0c0 100644 --- a/packages/contracts/src/release-metadata.json +++ b/packages/contracts/src/release-metadata.json @@ -1,5 +1,5 @@ { - "name": "PluginName", - "description": "Description.", + "name": "Multisig", + "description": "", "images": {} } diff --git a/packages/contracts/test/10_unit-testing/11_plugin.ts b/packages/contracts/test/10_unit-testing/11_plugin.ts index 715b0922..037dbb5a 100644 --- a/packages/contracts/test/10_unit-testing/11_plugin.ts +++ b/packages/contracts/test/10_unit-testing/11_plugin.ts @@ -1,102 +1,2285 @@ -import {PLUGIN_CONTRACT_NAME} from '../../plugin-settings'; +import {createDaoProxy} from '../20_integration-testing/test-helpers'; import { - DAOMock, - DAOMock__factory, - MyPlugin, - MyPlugin__factory, + Addresslist__factory, + IERC165Upgradeable__factory, + IMembership__factory, + IMultisig__factory, + IPlugin__factory, + IProposal__factory, + IProtocolVersion__factory, + ProxyFactory__factory, } from '../../typechain'; -import '../../typechain/src/MyPlugin'; -import {loadFixture} from '@nomicfoundation/hardhat-network-helpers'; +import {ExecutedEvent} from '../../typechain/@aragon/osx-commons-contracts/src/dao/IDAO'; +import {ProxyCreatedEvent} from '../../typechain/@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory'; +import { + ApprovedEvent, + ProposalCreatedEvent, + ProposalExecutedEvent, +} from '../../typechain/src/Multisig'; +import { + MULTISIG_EVENTS, + MULTISIG_INTERFACE, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, +} from '../multisig-constants'; +import {Multisig__factory, Multisig} from '../test-utils/typechain-versions'; +import { + getInterfaceId, + proposalIdToBytes32, + IDAO_EVENTS, + IMEMBERSHIP_EVENTS, + IPROPOSAL_EVENTS, + findEvent, + findEventTopicLog, + TIME, + DAO_PERMISSIONS, +} from '@aragon/osx-commons-sdk'; +import {DAO, DAOStructs, DAO__factory} from '@aragon/osx-ethers'; +import {loadFixture, time} from '@nomicfoundation/hardhat-network-helpers'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {BigNumber} from 'ethers'; -import {ethers, upgrades} from 'hardhat'; - -export type InitData = {number: BigNumber}; -export const defaultInitData: InitData = { - number: BigNumber.from(123), -}; - -export const STORE_PERMISSION_ID = ethers.utils.id('STORE_PERMISSION'); +import {ethers} from 'hardhat'; type FixtureResult = { deployer: SignerWithAddress; alice: SignerWithAddress; bob: SignerWithAddress; - plugin: MyPlugin; - daoMock: DAOMock; + carol: SignerWithAddress; + dave: SignerWithAddress; + eve: SignerWithAddress; + initializedPlugin: Multisig; + uninitializedPlugin: Multisig; + defaultInitData: { + members: string[]; + settings: Multisig.MultisigSettingsStruct; + }; + dao: DAO; + dummyActions: DAOStructs.ActionStruct[]; + dummyMetadata: string; }; async function fixture(): Promise { - const [deployer, alice, bob] = await ethers.getSigners(); - const daoMock = await new DAOMock__factory(deployer).deploy(); - const plugin = (await upgrades.deployProxy( - new MyPlugin__factory(deployer), - [daoMock.address, defaultInitData.number], + const [deployer, alice, bob, carol, dave, eve] = await ethers.getSigners(); + + // Deploy a DAO proxy. + const dummyMetadata = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes('0x123456789') + ); + const dao = await createDaoProxy(deployer, dummyMetadata); + + // Deploy a plugin proxy factory containing the multisig implementation. + const pluginImplementation = await new Multisig__factory(deployer).deploy(); + const proxyFactory = await new ProxyFactory__factory(deployer).deploy( + pluginImplementation.address + ); + + // Deploy an initialized plugin proxy. + const defaultInitData = { + members: [alice.address, bob.address, carol.address], + settings: { + onlyListed: true, + minApprovals: 2, + }, + }; + const pluginInitdata = pluginImplementation.interface.encodeFunctionData( + 'initialize', + [dao.address, defaultInitData.members, defaultInitData.settings] + ); + const deploymentTx1 = await proxyFactory.deployUUPSProxy(pluginInitdata); + const proxyCreatedEvent1 = await findEvent( + deploymentTx1, + proxyFactory.interface.getEvent('ProxyCreated').name + ); + const initializedPlugin = Multisig__factory.connect( + proxyCreatedEvent1.args.proxy, + deployer + ); + + // Deploy an initialized plugin proxy. + const deploymentTx2 = await proxyFactory.deployUUPSProxy([]); + const proxyCreatedEvent2 = await findEvent( + deploymentTx2, + proxyFactory.interface.getEvent('ProxyCreated').name + ); + const uninitializedPlugin = Multisig__factory.connect( + proxyCreatedEvent2.args.proxy, + deployer + ); + + // Provide a dummy action array. + const dummyActions: DAOStructs.ActionStruct[] = [ { - kind: 'uups', - initializer: 'initialize', - unsafeAllow: ['constructor'], - constructorArgs: [], - } - )) as unknown as MyPlugin; - - return {deployer, alice, bob, plugin, daoMock}; + to: deployer.address, + data: '0x1234', + value: 0, + }, + ]; + + return { + deployer, + alice, + bob, + carol, + dave, + eve, + initializedPlugin, + uninitializedPlugin, + defaultInitData, + dao, + dummyActions, + dummyMetadata, + }; } -describe(PLUGIN_CONTRACT_NAME, function () { +describe('Multisig', function () { describe('initialize', async () => { it('reverts if trying to re-initialize', async () => { - const {plugin, daoMock} = await loadFixture(fixture); + const {dao, initializedPlugin, defaultInitData} = await loadFixture( + fixture + ); + + // Try to reinitialize the initialized plugin. await expect( - plugin.initialize(daoMock.address, defaultInitData.number) + initializedPlugin.initialize( + dao.address, + defaultInitData.members, + defaultInitData.settings + ) ).to.be.revertedWith('Initializable: contract is already initialized'); }); - it('stores the number', async () => { - const {plugin} = await loadFixture(fixture); + it('adds the initial addresses to the address list', async () => { + const { + dao, + uninitializedPlugin: plugin, + defaultInitData, + } = await loadFixture(fixture); + + // Check that the uninitialized plugin has no members. + expect(await plugin.addresslistLength()).to.equal(0); + + // Initialize the plugin. + await plugin.initialize( + dao.address, + defaultInitData.members, + defaultInitData.settings + ); + + // Check that all members from the init data have been listed as members. + expect(await plugin.addresslistLength()).to.equal( + defaultInitData.members.length + ); + const promises = defaultInitData.members.map(member => + plugin.isListed(member) + ); + (await Promise.all(promises)).forEach(isListedResult => { + expect(isListedResult).to.be.true; + }); + }); + + it('sets the `minApprovals`', async () => { + const {initializedPlugin, defaultInitData} = await loadFixture(fixture); + expect( + (await initializedPlugin.multisigSettings()).minApprovals + ).to.be.eq(defaultInitData.settings.minApprovals); + }); + + it('sets `onlyListed`', async () => { + const {initializedPlugin, defaultInitData} = await loadFixture(fixture); + expect((await initializedPlugin.multisigSettings()).onlyListed).to.be.eq( + defaultInitData.settings.onlyListed + ); + }); + + it('emits `MultisigSettingsUpdated` during initialization', async () => { + const {uninitializedPlugin, defaultInitData, dao} = await loadFixture( + fixture + ); + await expect( + uninitializedPlugin.initialize( + dao.address, + defaultInitData.members, + defaultInitData.settings + ) + ) + .to.emit(uninitializedPlugin, MULTISIG_EVENTS.MultisigSettingsUpdated) + .withArgs( + defaultInitData.settings.onlyListed, + defaultInitData.settings.minApprovals + ); + }); + + it('reverts if the member list is longer than uint16 max', async () => { + const {uninitializedPlugin, alice, defaultInitData, dao} = + await loadFixture(fixture); + + // Create a member list causing an overflow during initialization. + const uint16MaxValue = 2 ** 16 - 1; // = 65535 + const overflowingMemberList = new Array(uint16MaxValue + 1).fill( + alice.address + ); + + // Try to initialize the plugin with a list of new members causing an overflow. + await expect( + uninitializedPlugin.initialize( + dao.address, + overflowingMemberList, + defaultInitData.settings, + { + gasLimit: BigNumber.from(10).pow(8).toNumber(), + } + ) + ) + .to.revertedWithCustomError( + uninitializedPlugin, + 'AddresslistLengthOutOfBounds' + ) + .withArgs(uint16MaxValue, overflowingMemberList.length); + }); + }); + + describe('ERC-165', async () => { + it('does not support the empty interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + expect(await plugin.supportsInterface('0xffffffff')).to.be.false; + }); + + it('supports the `IERC165Upgradeable` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const iface = IERC165Upgradeable__factory.createInterface(); + expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true; + }); + + it('supports the `IPlugin` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const iface = IPlugin__factory.createInterface(); + expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true; + }); + + it('supports the `IProtocolVersion` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const iface = IProtocolVersion__factory.createInterface(); + expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true; + }); + + it('supports the `IProposal` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const iface = IProposal__factory.createInterface(); + expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true; + }); + + it('supports the `IMembership` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const iface = IMembership__factory.createInterface(); + expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true; + }); + + it('supports the `Addresslist` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const iface = Addresslist__factory.createInterface(); + expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true; + }); + + it('supports the `IMultisig` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const iface = IMultisig__factory.createInterface(); + expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true; + }); + + it('supports the `Multisig` interface', async () => { + const {initializedPlugin: plugin} = await loadFixture(fixture); + const interfaceId = getInterfaceId(MULTISIG_INTERFACE); + expect(await plugin.supportsInterface(interfaceId)).to.be.true; + }); + }); + + describe('updateMultisigSettings', async () => { + it('reverts if the caller misses the `UPDATE_MULTISIG_SETTINGS_PERMISSION` permission', async () => { + const { + alice, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); + + // Check that Alice hasn't `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission on the Multisig plugin. + expect( + await dao.hasPermission( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, + [] + ) + ).to.be.false; + + // Expect Alice's `updateMultisigSettings` call to be reverted because she hasn't `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` + // permission on the Multisig plugin. + const newSettings: Multisig.MultisigSettingsStruct = { + onlyListed: false, + minApprovals: 1, + }; + await expect(plugin.connect(alice).updateMultisigSettings(newSettings)) + .to.be.revertedWithCustomError(plugin, 'DaoUnauthorized') + .withArgs( + dao.address, + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + }); + + it('reverts when setting `minApprovals` to a value greater than the address list length', async () => { + const { + alice, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // Create settings where `minApprovals` is greater than the address list length + const addresslistLength = (await plugin.addresslistLength()).toNumber(); + const badSettings: Multisig.MultisigSettingsStruct = { + onlyListed: true, + minApprovals: addresslistLength + 1, + }; + + // Try to update the multisig settings + await expect(plugin.connect(alice).updateMultisigSettings(badSettings)) + .to.be.revertedWithCustomError(plugin, 'MinApprovalsOutOfBounds') + .withArgs(addresslistLength, badSettings.minApprovals); + }); + + it('reverts when setting `minApprovals` to 0', async () => { + const { + alice, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // Try as Alice to update the settings with `minApprovals` being 0. + const badSettings: Multisig.MultisigSettingsStruct = { + onlyListed: true, + minApprovals: 0, + }; + await expect(plugin.connect(alice).updateMultisigSettings(badSettings)) + .to.be.revertedWithCustomError(plugin, 'MinApprovalsOutOfBounds') + .withArgs(1, 0); + }); + + it('emits `MultisigSettingsUpdated` when `updateMultisigSettings` gets called', async () => { + const { + alice, + initializedPlugin: plugin, + defaultInitData, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // Update the settings as Alice. + await expect( + plugin.connect(alice).updateMultisigSettings(defaultInitData.settings) + ) + .to.emit(plugin, MULTISIG_EVENTS.MultisigSettingsUpdated) + .withArgs( + defaultInitData.settings.onlyListed, + defaultInitData.settings.minApprovals + ); + }); + }); + + describe('isListed', async () => { + it('returns false, if a user is not listed', async () => { + const {dave, initializedPlugin: plugin} = await loadFixture(fixture); + expect(await plugin.isListed(dave.address)).to.equal(false); + }); - expect(await plugin.number()).to.equal(defaultInitData.number); + it('returns true, if a user is listed', async () => { + const {alice, initializedPlugin: plugin} = await loadFixture(fixture); + expect(await plugin.isListed(alice.address)).to.equal(true); }); }); - describe('storeNumber', async () => { - it('reverts if sender lacks permission', async () => { - const newNumber = BigNumber.from(456); + describe('isMember', async () => { + it('returns false, if user is not a member', async () => { + const {dave, initializedPlugin: plugin} = await loadFixture(fixture); + expect(await plugin.isMember(dave.address)).to.be.false; + }); - const {bob, plugin, daoMock} = await loadFixture(fixture); + it('returns true if user a user is a member', async () => { + const {alice, initializedPlugin: plugin} = await loadFixture(fixture); + expect(await plugin.isMember(alice.address)).to.be.true; + }); + }); - expect(await daoMock.hasPermissionReturnValueMock()).to.equal(false); + describe('addAddresses', async () => { + it('reverts if the caller misses the `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission', async () => { + const { + alice, + dave, + eve, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); - await expect(plugin.connect(bob).storeNumber(newNumber)) + // Check that the Alice hasn't `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission on the Multisig plugin. + expect( + await dao.hasPermission( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, + [] + ) + ).to.be.false; + + // Expect Alice's `addAddresses` call to be reverted because she hasn't `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` + // permission on the Multisig plugin. + await expect( + plugin.connect(alice).addAddresses([dave.address, eve.address]) + ) .to.be.revertedWithCustomError(plugin, 'DaoUnauthorized') .withArgs( - daoMock.address, + dao.address, plugin.address, - bob.address, - STORE_PERMISSION_ID + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID ); }); - it('stores the number', async () => { - const newNumber = BigNumber.from(456); + it('reverts if the member list would become longer than uint16 max', async () => { + const { + initializedPlugin: plugin, + alice, + dave, + dao, + } = await loadFixture(fixture); - const {plugin, daoMock} = await loadFixture(fixture); - await daoMock.setHasPermissionReturnValueMock(true); + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); - await expect(plugin.storeNumber(newNumber)).to.not.be.reverted; - expect(await plugin.number()).to.equal(newNumber); + const currentMemberCount = ( + await plugin.callStatic.addresslistLength() + ).toNumber(); + + // Create list of new members causing an overflow. + const uint16MaxValue = 2 ** 16 - 1; // = 65535 + const overflowingNewMemberList = new Array( + uint16MaxValue - currentMemberCount + 1 + ).fill(dave.address); + + // Try to add a list of new members causing an overflow as Alice. + await expect(plugin.connect(alice).addAddresses(overflowingNewMemberList)) + .to.revertedWithCustomError(plugin, 'AddresslistLengthOutOfBounds') + .withArgs(uint16MaxValue, uint16MaxValue + 1); }); - it('emits the NumberStored event', async () => { - const newNumber = BigNumber.from(456); + it('adds new members to the address list and emit the `MembersAdded` event', async () => { + const { + alice, + dave, + eve, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // Check that Dave and Eve are not listed yet. + expect(await plugin.isListed(dave.address)).to.equal(false); + expect(await plugin.isListed(eve.address)).to.equal(false); + + // Call `addAddresses` as Alice to add Dave and Eve. + await expect( + plugin.connect(alice).addAddresses([dave.address, eve.address]) + ) + .to.emit(plugin, IMEMBERSHIP_EVENTS.MembersAdded) + .withArgs([dave.address, eve.address]); + + // Check that Dave and Eve are listed now. + expect(await plugin.isListed(dave.address)).to.equal(true); + expect(await plugin.isListed(eve.address)).to.equal(true); + }); + }); + + describe('removeAddresses', async () => { + it('reverts if the caller misses the `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission', async () => { + const { + alice, + bob, + carol, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); + + // Check that Alice hasn't `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission on the Multisig plugin. + expect( + await dao.hasPermission( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, + [] + ) + ).to.be.false; + + // Expect Alice's `removeAddresses` call to be reverted because she hasn't `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` + // permission on the Multisig plugin. + await expect( + plugin.connect(alice).removeAddresses([bob.address, carol.address]) + ) + .to.be.revertedWithCustomError(plugin, 'DaoUnauthorized') + .withArgs( + dao.address, + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + }); + + it('removes users from the address list and emit the `MembersRemoved` event', async () => { + const { + alice, + bob, + carol, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // Check that Alice, Bob, and Carol are listed. + expect(await plugin.isListed(alice.address)).to.equal(true); + expect(await plugin.isListed(bob.address)).to.equal(true); + expect(await plugin.isListed(carol.address)).to.equal(true); + + // Call `removeAddresses` as Alice to remove Bob. + await expect(plugin.connect(alice).removeAddresses([bob.address])) + .to.emit(plugin, IMEMBERSHIP_EVENTS.MembersRemoved) + .withArgs([bob.address]); + + // Check that Bob is removed while Alice and Carol remains listed. + expect(await plugin.isListed(alice.address)).to.equal(true); + expect(await plugin.isListed(bob.address)).to.equal(false); + expect(await plugin.isListed(carol.address)).to.equal(true); + }); + + it('reverts if the address list would become empty', async () => { + const { + alice, + initializedPlugin: plugin, + defaultInitData, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // Try to remove all members. + await expect( + plugin.connect(alice).removeAddresses(defaultInitData.members) + ) + .to.be.revertedWithCustomError(plugin, 'MinApprovalsOutOfBounds') + .withArgs(0, defaultInitData.settings.minApprovals); + }); + + it('reverts if the address list would become shorter than the current minimum approval parameter requires', async () => { + const { + alice, + carol, + initializedPlugin: plugin, + defaultInitData, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // Initially, there are 3 members and `minApprovals` is 2. + // Remove one member, which is ok. + await expect(plugin.connect(alice).removeAddresses([carol.address])).not + .to.be.reverted; + + // Try to remove another member, which will revert. + await expect(plugin.connect(alice).removeAddresses([alice.address])) + .to.be.revertedWithCustomError(plugin, 'MinApprovalsOutOfBounds') + .withArgs( + (await plugin.addresslistLength()).sub(1), + defaultInitData.settings.minApprovals + ); + }); + }); + + describe('createProposal', async () => { + it('increments the proposal count', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Check that the proposal count is 0. + expect(await plugin.proposalCount()).to.equal(0); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + // Check that the proposal count is 1. + expect(await plugin.proposalCount()).to.equal(1); + + // Create another proposal as Alice. + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + + // Check that the proposal count is 2. + expect(await plugin.proposalCount()).to.equal(2); + }); + + it('creates unique proposal IDs for each proposal', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Make a static call to `createProposal` to get the first proposal ID ahead of time. + const endDate = (await time.latest()) + TIME.HOUR; + const proposalId0 = await plugin + .connect(alice) + .callStatic.createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + + // Create the new proposal as Alice. + await expect( + plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ) + ).not.to.be.reverted; + + // Make a static call to `createProposal` to get the next proposal ID ahead of time. + const proposalId1 = await plugin + .connect(alice) + .callStatic.createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + + // Check that the proposal IDs are as expected. + expect(proposalId0).to.equal(0); + expect(proposalId1).to.equal(1); + }); + + it('emits the `ProposalCreated` event', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + } = await loadFixture(fixture); + + // Create a proposal as Alice and check the event arguments. + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + const expectedProposalId = 0; + await expect( + plugin + .connect(alice) + .createProposal( + dummyMetadata, + [], + 0, + false, + false, + startDate, + endDate + ) + ) + .to.emit(plugin, IPROPOSAL_EVENTS.ProposalCreated) + .withArgs( + expectedProposalId, + alice.address, + startDate, + endDate, + dummyMetadata, + [], + 0 + ); + }); + + it('reverts if the multisig settings have been changed in the same block', async () => { + const { + alice, + initializedPlugin: plugin, + dao, + } = await loadFixture(fixture); + + // Grant Alice the permission to update the settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + const newSettings = { + onlyListed: false, + minApprovals: 1, + }; + + /* Make two calls to update the settings in the same block. */ + // Disable auto-mining so that both proposals end up in the same block. + await ethers.provider.send('evm_setAutomine', [false]); + // Update #1 + await plugin.connect(alice).updateMultisigSettings(newSettings); + // Update #2 + await plugin.connect(alice).updateMultisigSettings(newSettings); + // Re-enable auto-mining so that the remaining tests run normally. + await ethers.provider.send('evm_setAutomine', [true]); + }); + + it('reverts if the multisig settings have been changed in the same block via the proposals process', async () => { + const { + alice, + uninitializedPlugin: plugin, + dummyMetadata, + dao, + } = await loadFixture(fixture); + await plugin.initialize(dao.address, [alice.address], { + onlyListed: true, + minApprovals: 1, + }); + + // Grant permissions between the DAO and the plugin. + await dao.grant( + plugin.address, + dao.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Create an action calling `updateMultisigSettings`. + const updateMultisigSettingsAction = { + to: plugin.address, + value: 0, + data: plugin.interface.encodeFunctionData('updateMultisigSettings', [ + { + onlyListed: false, + minApprovals: 1, + }, + ]), + }; + + /* Create two proposals to update the settings in the same block. */ + const endDate = (await time.latest()) + TIME.HOUR; + + // Disable auto-mining so that both proposals end up in the same block. + await ethers.provider.send('evm_setAutomine', [false]); + + // Create and execute proposal #1 calling `updateMultisigSettings`. + await plugin.connect(alice).createProposal( + dummyMetadata, + [updateMultisigSettingsAction], + 0, + true, // approve + true, // execute + 0, + endDate + ); + + // Try to call update the settings a second time. + await expect( + plugin.connect(alice).createProposal( + dummyMetadata, + [updateMultisigSettingsAction], + 0, + false, // approve + false, // execute + 0, + endDate + ) + ) + .to.revertedWithCustomError(plugin, 'ProposalCreationForbidden') + .withArgs(alice.address); + + // Re-enable auto-mining so that the remaining tests run normally. + await ethers.provider.send('evm_setAutomine', [true]); + }); + + describe('`onlyListed` is set to `false`', async () => { + it('creates a proposal when an unlisted accounts is calling', async () => { + const { + alice, + dave, + initializedPlugin: plugin, + dao, + dummyMetadata, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + // As Alice, set `onlyListed` to `false`. + await plugin.connect(alice).updateMultisigSettings({ + minApprovals: 2, + onlyListed: false, + }); + + // Create a proposal as Dave (who is not listed). + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + + const expectedProposalId = 0; + + await expect( + plugin + .connect(dave) // Dave is not listed. + .createProposal( + dummyMetadata, + [], + 0, + false, + false, + startDate, + endDate + ) + ) + .to.emit(plugin, IPROPOSAL_EVENTS.ProposalCreated) + .withArgs( + expectedProposalId, + dave.address, + startDate, + endDate, + dummyMetadata, + [], + 0 + ); + }); + }); + + describe('`onlyListed` is set to `true`', async () => { + it('reverts if the caller is not listed and only listed accounts can create proposals', async () => { + const { + dave, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Try to create a proposal as Dave (who is not listed), which should revert. + const endDate = (await time.latest()) + TIME.HOUR; + await expect( + plugin + .connect(dave) // Dave is not listed. + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ) + ) + .to.be.revertedWithCustomError(plugin, 'ProposalCreationForbidden') + .withArgs(dave.address); + }); + + it('reverts if caller is not listed in the current block although she was listed in the last block', async () => { + const { + alice, + carol, + dave, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Grant Alice the permission to update settings. + await dao.grant( + plugin.address, + alice.address, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID + ); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Disable auto-mining so that all subsequent transactions end up in the same block. + await ethers.provider.send('evm_setAutomine', [false]); + const expectedSnapshotBlockNumber = ( + await ethers.provider.getBlock('latest') + ).number; + + // Transaction 1 & 2: Add Dave and remove Carol. + const tx1 = await plugin.connect(alice).addAddresses([dave.address]); + const tx2 = await plugin + .connect(alice) + .removeAddresses([carol.address]); + + // Transaction 3: Expect the proposal creation to fail for Carol because she was removed as a member in transaction 2. + + await expect( + plugin + .connect(carol) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ) + ) + .to.be.revertedWithCustomError(plugin, 'ProposalCreationForbidden') + .withArgs(carol.address); + + // Transaction 4: Create the proposal as Dave + const tx4 = await plugin + .connect(dave) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Check the listed members before the block is mined. + expect(await plugin.isListed(carol.address)).to.equal(true); + expect(await plugin.isListed(dave.address)).to.equal(false); + + // Mine the block + await ethers.provider.send('evm_mine', []); + const minedBlockNumber = (await ethers.provider.getBlock('latest')) + .number; + + // Expect all transaction receipts to be in the same block after the snapshot block. + expect((await tx1.wait()).blockNumber).to.equal(minedBlockNumber); + expect((await tx2.wait()).blockNumber).to.equal(minedBlockNumber); + expect((await tx4.wait()).blockNumber).to.equal(minedBlockNumber); + expect(minedBlockNumber).to.equal(expectedSnapshotBlockNumber + 1); + + // Expect the listed member to have changed. + expect(await plugin.isListed(carol.address)).to.equal(false); + expect(await plugin.isListed(dave.address)).to.equal(true); + + // Check the `ProposalCreatedEvent` for the creator and proposalId. + const event = await findEvent( + tx4, + 'ProposalCreated' + ); + expect(event.args.proposalId).to.equal(id); + expect(event.args.creator).to.equal(dave.address); + + // Check that the snapshot block stored in the proposal struct. + const proposal = await plugin.getProposal(id); + expect(proposal.parameters.snapshotBlock).to.equal( + expectedSnapshotBlockNumber + ); + + // Re-enable auto-mining so that the remaining tests run normally. + await ethers.provider.send('evm_setAutomine', [true]); + }); + }); + + it('creates a proposal successfully and does not approve if not specified', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + defaultInitData, + dummyMetadata, + } = await loadFixture(fixture); + + // Create a proposal (ID 0) as Alice but don't approve on creation. + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + const allowFailureMap = 0; + await time.setNextBlockTimestamp(startDate); + const id = 0; + + const approveProposal = false; + + await expect( + plugin.connect(alice).createProposal( + dummyMetadata, + [], + allowFailureMap, + approveProposal, // false + false, + startDate, + endDate + ) + ) + .to.emit(plugin, IPROPOSAL_EVENTS.ProposalCreated) + .withArgs(id, alice.address, startDate, endDate, dummyMetadata, [], 0); + + const latestBlock = await ethers.provider.getBlock('latest'); + + // Check that the proposal was created as expected and has 0 approvals. + const proposal = await plugin.getProposal(id); + expect(proposal.executed).to.equal(false); + expect(proposal.allowFailureMap).to.equal(0); + expect(proposal.parameters.snapshotBlock).to.equal( + latestBlock.number - 1 + ); + expect(proposal.parameters.minApprovals).to.equal( + defaultInitData.settings.minApprovals + ); + expect(proposal.parameters.startDate).to.equal(startDate); + expect(proposal.parameters.endDate).to.equal(endDate); + expect(proposal.actions.length).to.equal(0); + expect(proposal.approvals).to.equal(0); + + // Check that Alice hasn't approved the proposal yet. + expect(await plugin.canApprove(id, alice.address)).to.be.true; + // Check that, e.g., Bob hasn't approved the proposal yet. + expect(await plugin.canApprove(id, bob.address)).to.be.true; + }); + + it('creates a proposal successfully and approves if specified', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + defaultInitData, + dummyMetadata, + } = await loadFixture(fixture); + + // Create a proposal as Alice and approve on creation. + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + const allowFailureMap = 1; + const approveProposal = true; + + await time.setNextBlockTimestamp(startDate); + + const id = 0; + await expect( + plugin.connect(alice).createProposal( + dummyMetadata, + [], + allowFailureMap, + approveProposal, // true + false, + startDate, + endDate + ) + ) + .to.emit(plugin, IPROPOSAL_EVENTS.ProposalCreated) + .withArgs( + id, + alice.address, + startDate, + endDate, + dummyMetadata, + [], + allowFailureMap + ) + .to.emit(plugin, MULTISIG_EVENTS.Approved) + .withArgs(id, alice.address); + + const latestBlock = await ethers.provider.getBlock('latest'); + + // Check that the proposal was created as expected and has 1 approval. + const proposal = await plugin.getProposal(id); + expect(proposal.executed).to.equal(false); + expect(proposal.allowFailureMap).to.equal(allowFailureMap); + expect(proposal.parameters.snapshotBlock).to.equal( + latestBlock.number - 1 + ); + expect(proposal.parameters.minApprovals).to.equal( + defaultInitData.settings.minApprovals + ); + expect(proposal.parameters.startDate).to.equal(startDate); + expect(proposal.parameters.endDate).to.equal(endDate); + expect(proposal.actions.length).to.equal(0); + expect(proposal.approvals).to.equal(1); + + // Check that Alice has approved the proposal already. + expect(await plugin.canApprove(id, alice.address)).to.be.false; + // Check that, e.g., Bob hasn't approved the proposal yet. + expect(await plugin.canApprove(id, bob.address)).to.be.true; + }); + + it('reverts if startDate < now', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Set the clock to the start date. + const startDate = (await time.latest()) + TIME.MINUTE; + await time.setNextBlockTimestamp(startDate); + + // Try to create a proposal as Alice where the start date lies in the past. + const startDateInThePast = startDate - 1; + const endDate = startDate + TIME.HOUR; + await expect( + plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + true, + false, + startDateInThePast, + endDate + ) + ) + .to.be.revertedWithCustomError(plugin, 'DateOutOfBounds') + .withArgs(startDate, startDateInThePast); + }); + + it('reverts if endDate < startDate', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Try to create a proposal as Alice where the end date is before the start date + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate - 1; // endDate < startDate + await expect( + plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + true, + false, + startDate, + endDate + ) + ) + .to.be.revertedWithCustomError(plugin, 'DateOutOfBounds') + .withArgs(startDate, endDate); + }); + }); + + context('Approving and executing proposals', async () => { + describe('canApprove', async () => { + it('returns `false` if the proposal is already executed', async () => { + const { + alice, + bob, + carol, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Check that Carol can approve. + expect(await plugin.canApprove(id, carol.address)).to.be.true; + + // Approve with Alice. + await plugin.connect(alice).approve(id, false); + // Approve and execute with Bob. + await plugin.connect(bob).approve(id, true); + + // Check that the proposal got executed. + expect((await plugin.getProposal(id)).executed).to.be.true; + + // Check that Carol cannot approve the executed proposal anymore. + expect(await plugin.canApprove(id, carol.address)).to.be.false; + }); + + it('returns `false` if the approver is not listed', async () => { + const { + alice, + dave, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Check that Dave who is not listed cannot approve. + expect(await plugin.isListed(dave.address)).to.be.false; + expect(await plugin.canApprove(id, dave.address)).to.be.false; + }); + + it('returns `false` if the approver has already approved', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + await plugin.connect(alice).approve(id, false); + expect(await plugin.canApprove(id, alice.address)).to.be.false; + }); + + it('returns `true` if the approver is listed', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + expect(await plugin.canApprove(id, alice.address)).to.be.true; + }); + + it("returns `false` if the proposal hasn't started yet", async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + startDate, + endDate + ); + const id = 0; + + expect(await plugin.canApprove(id, alice.address)).to.be.false; + + await time.increaseTo(startDate); + + expect(await plugin.canApprove(id, alice.address)).to.be.true; + }); + + it('returns `false` if the proposal has ended', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + expect(await plugin.canApprove(id, alice.address)).to.be.true; + + await time.increaseTo(endDate + 1); + + expect(await plugin.canApprove(id, alice.address)).to.be.false; + }); + }); + + describe('hasApproved', async () => { + it("returns `false` if user hasn't approved yet", async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + expect(await plugin.hasApproved(id, alice.address)).to.be.false; + }); + + it('returns `true` if user has approved', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + await plugin.connect(alice).approve(id, false); + expect(await plugin.hasApproved(id, alice.address)).to.be.true; + }); + }); + + describe('approve', async () => { + it('reverts when approving multiple times', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + await plugin.connect(alice).approve(id, true); + + // Try to vote again + await expect(plugin.connect(alice).approve(id, true)) + .to.be.revertedWithCustomError(plugin, 'ApprovalCastForbidden') + .withArgs(id, alice.address); + }); + + it('reverts if minimal approval is not met yet', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + dao, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0) + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` permission on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Try to execute the proposals although `minApprovals` has not been reached yet. + const proposal = await plugin.getProposal(id); + expect(proposal.approvals).to.eq(0); + await expect(plugin.connect(alice).execute(id)) + .to.be.revertedWithCustomError(plugin, 'ProposalExecutionForbidden') + .withArgs(id); + }); + + it('approves with the caller address', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + // Create a proposal (with ID 0). + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Check that there are 0 approvals yet. + expect((await plugin.getProposal(id)).approvals).to.equal(0); + + // Approve the proposal as Alice. + const tx = await plugin.connect(alice).approve(id, false); + + // Check the `Approved` event and make sure that Alice is emitted as the approver. + const event = await findEvent(tx, 'Approved'); + expect(event.args.proposalId).to.eq(id); + expect(event.args.approver).to.eq(alice.address); + + // Check that the approval was counted. + expect((await plugin.getProposal(id)).approvals).to.equal(1); + }); + + it("reverts if the proposal hasn't started yet", async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice that didn't started yet. + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + startDate, + endDate + ); + const id = 0; + + // Try to approve the proposal as Alice although being before the start date. + await expect(plugin.connect(alice).approve(id, false)) + .to.be.revertedWithCustomError(plugin, 'ApprovalCastForbidden') + .withArgs(0, alice.address); + + // Advance to the start date. + await time.increaseTo(startDate); + + // Approve as Alice and check that this doesn't revert. + await expect(plugin.connect(alice).approve(id, false)).not.to.be + .reverted; + }); + + it('reverts if the proposal has ended', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice that starts now. + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Advance time after the end date. + await time.increaseTo(endDate + 1); + + await expect(plugin.connect(alice).approve(id, false)) + .to.be.revertedWithCustomError(plugin, 'ApprovalCastForbidden') + .withArgs(id, alice.address); + }); + }); + + describe('canExecute', async () => { + it('returns `false` if the proposal has not reached the minimum approval yet', async () => { + const { + alice, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Check that `minApprovals` isn't met yet. + const proposal = await plugin.getProposal(id); + expect(proposal.approvals).to.be.lt(proposal.parameters.minApprovals); + + // Check that the proposal can not be executed. + expect(await plugin.canExecute(id)).to.be.false; + }); + + it('returns `false` if the proposal is already executed', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` permission on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Approve as Alice. + await plugin.connect(alice).approve(id, false); + // Approve and execute as Bob. + await plugin.connect(bob).approve(id, true); + + // Check that the proposal got executed. + expect((await plugin.getProposal(id)).executed).to.be.true; + + // Check that it cannot be executed again. + expect(await plugin.canExecute(id)).to.be.false; + }); + + it('returns `true` if the proposal can be executed', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); + + expect((await plugin.getProposal(id)).executed).to.be.false; + expect(await plugin.canExecute(id)).to.be.true; + }); + + it("returns `false` if the proposal hasn't started yet", async () => { + const { + alice, + bob, + carol, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + startDate, + endDate + ); + const id = 0; + + expect(await plugin.canExecute(id)).to.be.false; + + await time.increaseTo(startDate); + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); + await plugin.connect(carol).approve(id, false); + + expect(await plugin.canExecute(id)).to.be.true; + }); + + it('returns `false` if the proposal has ended', async () => { + const { + alice, + bob, + carol, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); + await plugin.connect(carol).approve(id, false); + + expect(await plugin.canExecute(id)).to.be.true; + + await time.increaseTo(endDate + 1); + + expect(await plugin.canExecute(id)).to.be.false; + }); + }); + + describe('execute', async () => { + it('reverts if the minimum approval is not met', async () => { + const { + alice, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` permission on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Check that proposal cannot be executed if the minimum approval is not met yet. + await expect(plugin.execute(id)) + .to.be.revertedWithCustomError(plugin, 'ProposalExecutionForbidden') + .withArgs(id); + }); + + it('executes if the minimum approval is met', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + defaultInitData, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` permission on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Approve with Alice and Bob. + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); + + // Check that the `minApprovals` threshold is met. + const proposal = await plugin.getProposal(id); + expect(proposal.parameters.minApprovals).to.equal( + defaultInitData.settings.minApprovals + ); + expect(proposal.approvals).to.be.eq( + defaultInitData.settings.minApprovals + ); + + // Check that the proposal can be executed. + expect(await plugin.canExecute(id)).to.be.true; + + // Check that it executes. + await expect(plugin.execute(id)).not.to.be.reverted; + }); + + it('executes if the minimum approval is met and can be called by an unlisted accounts', async () => { + const { + alice, + bob, + dave, + initializedPlugin: plugin, + defaultInitData, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + const endDate = (await time.latest()) + TIME.HOUR; + + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); + + const proposal = await plugin.getProposal(id); + + expect(proposal.parameters.minApprovals).to.equal( + defaultInitData.settings.minApprovals + ); + expect(proposal.approvals).to.be.eq( + defaultInitData.settings.minApprovals + ); + + expect(await plugin.canExecute(id)).to.be.true; + expect(await plugin.isListed(dave.address)).to.be.false; // Dave is not listed + await expect(plugin.connect(dave).execute(id)).not.to.be.reverted; + }); + + it('executes if the minimum approval is met when multisig with the `tryExecution` option', async () => { + const { + alice, + bob, + carol, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` permission on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Approve and try execution as Alice although the `minApprovals` threshold is not met yet. + let tx = await plugin.connect(alice).approve(id, true); + await expect( + findEventTopicLog( + tx, + DAO__factory.createInterface(), + IDAO_EVENTS.Executed + ) + ).to.rejectedWith( + `Event "${IDAO_EVENTS.Executed}" could not be found in transaction ${tx.hash}.` + ); + + expect(await plugin.canExecute(id)).to.equal(false); + + // Approve but do not try execution as Bob although the `minApprovals` threshold is reached now. + tx = await plugin.connect(bob).approve(id, false); + await expect( + findEventTopicLog( + tx, + DAO__factory.createInterface(), + IDAO_EVENTS.Executed + ) + ).to.rejectedWith( + `Event "${IDAO_EVENTS.Executed}" could not be found in transaction ${tx.hash}.` + ); + + // Approve and try execution as Carol while `minApprovals` threshold is reached already. + tx = await plugin.connect(carol).approve(id, true); + + // Check that the proposal got executed by checking the `Executed` event emitted by the DAO. + { + const event = await findEventTopicLog( + tx, + DAO__factory.createInterface(), + IDAO_EVENTS.Executed + ); + + expect(event.args.actor).to.equal(plugin.address); + expect(event.args.callId).to.equal(proposalIdToBytes32(id)); + expect(event.args.actions.length).to.equal(1); + expect(event.args.actions[0].to).to.equal(dummyActions[0].to); + expect(event.args.actions[0].value).to.equal(dummyActions[0].value); + expect(event.args.actions[0].data).to.equal(dummyActions[0].data); + expect(event.args.execResults).to.deep.equal(['0x']); + + const prop = await plugin.getProposal(id); + expect(prop.executed).to.equal(true); + } + + // Check that the proposal got executed by checking the `ProposalExecuted` event emitted by the plugin. + { + const event = await findEvent( + tx, + IPROPOSAL_EVENTS.ProposalExecuted + ); + expect(event.args.proposalId).to.equal(id); + } + + // Try executing it again. + await expect(plugin.execute(id)) + .to.be.revertedWithCustomError(plugin, 'ProposalExecutionForbidden') + .withArgs(id); + }); + + it('emits the `ProposalExecuted` and `Executed` events', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Approve the proposal as Alice and Bob. + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); + + // Execute the proposal and check that the `Executed` and `ProposalExecuted` event is emitted + // and that the `Approved` event is not emitted. + await expect(plugin.connect(alice).execute(id)) + .to.emit(dao, IDAO_EVENTS.Executed) + .to.emit(plugin, IPROPOSAL_EVENTS.ProposalExecuted) + .to.not.emit(plugin, MULTISIG_EVENTS.Approved); + }); + + it('emits the `Approved`, `ProposalExecuted`, and `Executed` events if execute is called inside the `approve` method', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const endDate = (await time.latest()) + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` permission on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Approve the proposal as Alice. + await plugin.connect(alice).approve(id, false); + + // Approve and execute the proposal as Bob and check that the `Executed`, `ProposalExecuted`, and `Approved` + // event is not emitted. + await expect(plugin.connect(bob).approve(id, true)) + .to.emit(dao, IDAO_EVENTS.Executed) + .to.emit(plugin, IPROPOSAL_EVENTS.ProposalExecuted) + .to.emit(plugin, MULTISIG_EVENTS.Approved); + }); + + it("reverts if the proposal hasn't started yet", async () => { + const { + alice, + bob, + initializedPlugin: plugin, + dao, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + startDate, + endDate + ); + const id = 0; + + // Grant the plugin `EXECUTE_PERMISSION_ID` permission on the DAO. + await dao.grant( + dao.address, + plugin.address, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID + ); + + // Try to execute the proposal before the start date. + await expect(plugin.execute(id)) + .to.be.revertedWithCustomError(plugin, 'ProposalExecutionForbidden') + .withArgs(id); + + // Advance time to the start date. + await time.increaseTo(startDate); + + // Approve the proposal as Alice and Bob. + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); + + // Execute the proposal. + await expect(plugin.execute(id)).not.to.be.reverted; + }); + + it('reverts if the proposal has ended', async () => { + const { + alice, + bob, + initializedPlugin: plugin, + dummyMetadata, + dummyActions, + } = await loadFixture(fixture); + + // Create a proposal as Alice. + const startDate = (await time.latest()) + TIME.MINUTE; + const endDate = startDate + TIME.HOUR; + await plugin + .connect(alice) + .createProposal( + dummyMetadata, + dummyActions, + 0, + false, + false, + 0, + endDate + ); + const id = 0; + + // Approve the proposal but do not execute yet. + await plugin.connect(alice).approve(id, false); + await plugin.connect(bob).approve(id, false); - const {plugin, daoMock} = await loadFixture(fixture); - await daoMock.setHasPermissionReturnValueMock(true); + // Advance time after the end date + await time.increase(endDate + 1); - await expect(plugin.storeNumber(newNumber)) - .to.emit(plugin, 'NumberStored') - .withArgs(newNumber); + // Try to execute the proposal after the end date. + await expect( + plugin.connect(bob).execute(id) + ).to.be.revertedWithCustomError(plugin, 'ProposalExecutionForbidden'); + }); }); }); }); diff --git a/packages/contracts/test/10_unit-testing/12_plugin-setup.ts b/packages/contracts/test/10_unit-testing/12_plugin-setup.ts index 381580b2..86c0d758 100644 --- a/packages/contracts/test/10_unit-testing/12_plugin-setup.ts +++ b/packages/contracts/test/10_unit-testing/12_plugin-setup.ts @@ -1,49 +1,71 @@ -import {PLUGIN_SETUP_CONTRACT_NAME} from '../../plugin-settings'; -import buildMetadata from '../../src/build-metadata.json'; +import {createDaoProxy} from '../20_integration-testing/test-helpers'; +import {METADATA, VERSION} from '../../plugin-settings'; +import {MultisigSetup, MultisigSetup__factory} from '../../typechain'; import { - DAOMock, - DAOMock__factory, - MyPluginSetup, - MyPluginSetup__factory, - MyPlugin__factory, -} from '../../typechain'; -import {STORE_PERMISSION_ID, defaultInitData} from './11_plugin'; + MULTISIG_INTERFACE, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, +} from '../multisig-constants'; +import {Multisig__factory, Multisig} from '../test-utils/typechain-versions'; import { - ADDRESS, + getInterfaceId, Operation, - PERMISSION_MANAGER_FLAGS, + DAO_PERMISSIONS, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS, getNamedTypesFromMetadata, } from '@aragon/osx-commons-sdk'; +import {DAO} from '@aragon/osx-ethers'; import {loadFixture} from '@nomicfoundation/hardhat-network-helpers'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {ethers} from 'hardhat'; +const abiCoder = ethers.utils.defaultAbiCoder; +const AddressZero = ethers.constants.AddressZero; + type FixtureResult = { deployer: SignerWithAddress; alice: SignerWithAddress; bob: SignerWithAddress; - pluginSetup: MyPluginSetup; + carol: SignerWithAddress; + pluginSetup: MultisigSetup; + defaultMembers: string[]; + defaultMultisigSettings: Multisig.MultisigSettingsStruct; prepareInstallationInputs: string; prepareUninstallationInputs: string; - daoMock: DAOMock; + dao: DAO; }; async function fixture(): Promise { - const [deployer, alice, bob] = await ethers.getSigners(); - const daoMock = await new DAOMock__factory(deployer).deploy(); - const pluginSetup = await new MyPluginSetup__factory(deployer).deploy(); + const [deployer, alice, bob, carol] = await ethers.getSigners(); + + // Deploy a DAO proxy. + const dummyMetadata = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes('0x123456789') + ); + const dao = await createDaoProxy(deployer, dummyMetadata); + + // Deploy a plugin setup contract + const pluginSetup = await new MultisigSetup__factory(deployer).deploy(); + // Provide default multisig settings + const defaultMembers = [alice.address, bob.address, carol.address]; + const defaultMultisigSettings: Multisig.MultisigSettingsStruct = { + onlyListed: true, + minApprovals: 1, + }; + + // Provide installation inputs const prepareInstallationInputs = ethers.utils.defaultAbiCoder.encode( getNamedTypesFromMetadata( - buildMetadata.pluginSetup.prepareInstallation.inputs + METADATA.build.pluginSetup.prepareInstallation.inputs ), - [defaultInitData.number] + [defaultMembers, Object.values(defaultMultisigSettings)] ); + // Provide uninstallation inputs const prepareUninstallationInputs = ethers.utils.defaultAbiCoder.encode( getNamedTypesFromMetadata( - buildMetadata.pluginSetup.prepareUninstallation.inputs + METADATA.build.pluginSetup.prepareUninstallation.inputs ), [] ); @@ -52,19 +74,188 @@ async function fixture(): Promise { deployer, alice, bob, + carol, pluginSetup, + defaultMembers, + defaultMultisigSettings, prepareInstallationInputs, prepareUninstallationInputs, - daoMock, + dao, }; } -describe(PLUGIN_SETUP_CONTRACT_NAME, function () { +describe('MultisigSetup', function () { + it('does not support the empty interface', async () => { + const {pluginSetup} = await loadFixture(fixture); + expect(await pluginSetup.supportsInterface('0xffffffff')).to.be.false; + }); + + it('has a multisig implementation supporting the correct interface', async () => { + const {deployer, pluginSetup} = await loadFixture(fixture); + + const factory = new Multisig__factory(deployer); + const multisigImplementation = factory.attach( + await pluginSetup.implementation() + ); + + expect( + await multisigImplementation.supportsInterface( + getInterfaceId(MULTISIG_INTERFACE) + ) + ).to.be.true; + }); + describe('prepareInstallation', async () => { - it('returns the plugin, helpers, and permissions', async () => { - const {deployer, pluginSetup, prepareInstallationInputs, daoMock} = + it('fails if data is empty, or not of minimum length', async () => { + const {pluginSetup, dao, prepareInstallationInputs} = await loadFixture( + fixture + ); + + // Try calling `prepareInstallation` without input data. + await expect(pluginSetup.prepareInstallation(dao.address, [])).to.be + .reverted; + + // Try calling `prepareInstallation` without input data of wrong length. + const trimmedData = prepareInstallationInputs.substring( + 0, + prepareInstallationInputs.length - 2 + ); + await expect(pluginSetup.prepareInstallation(dao.address, trimmedData)).to + .be.reverted; + + // Check that `prepareInstallation` can be called with the correct input data. + await expect( + pluginSetup.prepareInstallation(dao.address, prepareInstallationInputs) + ).not.to.be.reverted; + }); + + it('reverts if zero members are provided in the initialization data', async () => { + const {deployer, pluginSetup, dao, defaultMultisigSettings} = await loadFixture(fixture); + // Create input data containing an empty list of initial members. + const noMembers: string[] = []; + const wrongPrepareInstallationData = abiCoder.encode( + getNamedTypesFromMetadata( + METADATA.build.pluginSetup.prepareInstallation.inputs + ), + [noMembers, defaultMultisigSettings] + ); + + // Anticipate the plugin proxy address that will be deployed. + const nonce = await ethers.provider.getTransactionCount( + pluginSetup.address + ); + const anticipatedPluginAddress = ethers.utils.getContractAddress({ + from: pluginSetup.address, + nonce, + }); + const multisig = Multisig__factory.connect( + anticipatedPluginAddress, + deployer + ); + + // Try calling `prepareInstallation`, which will fail during plugin initialization because of the empty initial + // member list. + await expect( + pluginSetup.prepareInstallation( + dao.address, + wrongPrepareInstallationData + ) + ) + .to.be.revertedWithCustomError(multisig, 'MinApprovalsOutOfBounds') + .withArgs(0, 1); + }); + + it('reverts if the `minApprovals` value in `_data` is zero', async () => { + const {deployer, pluginSetup, dao} = await loadFixture(fixture); + + // Create input data containing a `minApprovals` threshold of 0. + const multisigSettings: Multisig.MultisigSettingsStruct = { + onlyListed: true, + minApprovals: 0, + }; + const members = [deployer.address]; + const wrongPrepareInstallationData = abiCoder.encode( + getNamedTypesFromMetadata( + METADATA.build.pluginSetup.prepareInstallation.inputs + ), + [members, multisigSettings] + ); + + // Anticipate the plugin proxy address that will be deployed. + const nonce = await ethers.provider.getTransactionCount( + pluginSetup.address + ); + const anticipatedPluginAddress = ethers.utils.getContractAddress({ + from: pluginSetup.address, + nonce, + }); + const multisig = Multisig__factory.connect( + anticipatedPluginAddress, + deployer + ); + + // Try calling `prepareInstallation`, which will fail during plugin initialization because of the invalid + // `minApprovals` value. + await expect( + pluginSetup.prepareInstallation( + dao.address, + wrongPrepareInstallationData + ) + ) + .to.be.revertedWithCustomError(multisig, 'MinApprovalsOutOfBounds') + .withArgs(1, 0); + }); + + it('reverts if the `minApprovals` value in `_data` is greater than the number of members', async () => { + const {deployer, pluginSetup, dao} = await loadFixture(fixture); + + // Create input data containing an initial member list with a length lower that the specified `minApprovals` + // threshold. + const multisigSettings: Multisig.MultisigSettingsStruct = { + onlyListed: true, + minApprovals: 2, + }; + const members = [deployer.address]; + const wrongPrepareInstallationData = abiCoder.encode( + getNamedTypesFromMetadata( + METADATA.build.pluginSetup.prepareInstallation.inputs + ), + [members, multisigSettings] + ); + + // Anticipate the plugin proxy address that will be deployed. + const nonce = await ethers.provider.getTransactionCount( + pluginSetup.address + ); + const anticipatedPluginAddress = ethers.utils.getContractAddress({ + from: pluginSetup.address, + nonce, + }); + const multisig = Multisig__factory.connect( + anticipatedPluginAddress, + deployer + ); + + // Try calling `prepareInstallation`, which will fail during plugin initialization because of the mismatch + // between the `minApprovals` value and the initial member list length. + await expect( + pluginSetup.prepareInstallation( + dao.address, + wrongPrepareInstallationData + ) + ) + .to.be.revertedWithCustomError(multisig, 'MinApprovalsOutOfBounds') + .withArgs(members.length, multisigSettings.minApprovals); + }); + + it('returns the plugin, helpers, and permissions', async () => { + const {pluginSetup, dao, prepareInstallationInputs} = await loadFixture( + fixture + ); + + // Anticipate the plugin proxy address that will be deployed. const nonce = await ethers.provider.getTransactionCount( pluginSetup.address ); @@ -73,63 +264,150 @@ describe(PLUGIN_SETUP_CONTRACT_NAME, function () { nonce, }); + // Make a static call to check that the plugin preparation data being returned is correct. const { plugin, preparedSetupData: {helpers, permissions}, } = await pluginSetup.callStatic.prepareInstallation( - daoMock.address, + dao.address, prepareInstallationInputs ); + // Check the return data. expect(plugin).to.be.equal(anticipatedPluginAddress); expect(helpers.length).to.be.equal(0); - expect(permissions.length).to.be.equal(1); + expect(permissions.length).to.be.equal(3); expect(permissions).to.deep.equal([ [ Operation.Grant, plugin, - daoMock.address, - PERMISSION_MANAGER_FLAGS.NO_CONDITION, - STORE_PERMISSION_ID, + dao.address, + AddressZero, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, + ], + [ + Operation.Grant, + plugin, + dao.address, + AddressZero, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS.UPGRADE_PLUGIN_PERMISSION_ID, + ], + [ + Operation.Grant, + dao.address, + plugin, + AddressZero, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID, ], ]); + }); + + it('sets up the plugin', async () => { + const { + deployer, + pluginSetup, + dao, + prepareInstallationInputs, + defaultMembers, + defaultMultisigSettings, + } = await loadFixture(fixture); + + // Anticipate the plugin proxy address that will be deployed. + const nonce = await ethers.provider.getTransactionCount( + pluginSetup.address + ); + const anticipatedPluginAddress = ethers.utils.getContractAddress({ + from: pluginSetup.address, + nonce, + }); + // Prepare the installation await pluginSetup.prepareInstallation( - daoMock.address, + dao.address, prepareInstallationInputs ); - const myPlugin = new MyPlugin__factory(deployer).attach(plugin); - // initialization is correct - expect(await myPlugin.dao()).to.eq(daoMock.address); - expect(await myPlugin.number()).to.be.eq(defaultInitData.number); + const plugin = Multisig__factory.connect( + anticipatedPluginAddress, + deployer + ); + + // Check that the plugin is initialized correctly. + expect(await plugin.dao()).to.eq(dao.address); + expect(await plugin.addresslistLength()).to.be.eq(defaultMembers.length); + const settings = await plugin.multisigSettings(); + expect(settings.onlyListed).to.equal(defaultMultisigSettings.onlyListed); + expect(settings.minApprovals).to.eq(defaultMultisigSettings.minApprovals); + }); + }); + + describe('prepareUpdate', async () => { + it('should return nothing', async () => { + const {pluginSetup, dao} = await loadFixture(fixture); + + // Make a static call to check that the plugin update data being returned is correct. + const prepareUpdateData = await pluginSetup.callStatic.prepareUpdate( + dao.address, + VERSION.build, + { + currentHelpers: [ + ethers.Wallet.createRandom().address, + ethers.Wallet.createRandom().address, + ], + data: '0x00', + plugin: ethers.Wallet.createRandom().address, + } + ); + // Check the return data. + expect(prepareUpdateData.initData).to.be.eq('0x'); + expect(prepareUpdateData.preparedSetupData.permissions).to.be.eql([]); + expect(prepareUpdateData.preparedSetupData.helpers).to.be.eql([]); }); }); describe('prepareUninstallation', async () => { - it('returns the permissions', async () => { - const {pluginSetup, daoMock, prepareUninstallationInputs} = - await loadFixture(fixture); + it('correctly returns permissions', async () => { + const {pluginSetup, dao, prepareUninstallationInputs} = await loadFixture( + fixture + ); - const dummyAddr = ADDRESS.ZERO; + // Use a random address to prepare an uninstallation. + // Note: Applying this uninstallation would fail because the PSP knows if the plugin was installed at some point. + const plugin = ethers.Wallet.createRandom().address; + // Make a static call to check that the plugin uninstallation data being returned is correct. const permissions = await pluginSetup.callStatic.prepareUninstallation( - daoMock.address, + dao.address, { - plugin: dummyAddr, + plugin, currentHelpers: [], data: prepareUninstallationInputs, } ); - expect(permissions.length).to.be.equal(1); + // Check the return data. + expect(permissions.length).to.be.equal(3); expect(permissions).to.deep.equal([ [ Operation.Revoke, - dummyAddr, - daoMock.address, - PERMISSION_MANAGER_FLAGS.NO_CONDITION, - STORE_PERMISSION_ID, + plugin, + dao.address, + AddressZero, + UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, + ], + [ + Operation.Revoke, + plugin, + dao.address, + AddressZero, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS.UPGRADE_PLUGIN_PERMISSION_ID, + ], + [ + Operation.Revoke, + dao.address, + plugin, + AddressZero, + DAO_PERMISSIONS.EXECUTE_PERMISSION_ID, ], ]); }); diff --git a/packages/contracts/test/20_integration-testing/21_deployment.ts b/packages/contracts/test/20_integration-testing/21_deployment.ts index 1bdcfb7f..eb6509e9 100644 --- a/packages/contracts/test/20_integration-testing/21_deployment.ts +++ b/packages/contracts/test/20_integration-testing/21_deployment.ts @@ -13,6 +13,8 @@ import { uploadToIPFS, } from '@aragon/osx-commons-sdk'; import { + DAO, + DAO__factory, PluginRepo, PluginRepoRegistry, PluginRepoRegistry__factory, @@ -31,13 +33,13 @@ describe(`Deployment on network '${productionNetworkName}'`, function () { expect(await pluginRepoRegistry.entries(pluginRepo.address)).to.be.true; }); - it('makes the deployer the repo maintainer', async () => { - const {deployer, pluginRepo} = await loadFixture(fixture); + it('gives the management DAO permissions over the repo', async () => { + const {pluginRepo, managementDaoProxy} = await loadFixture(fixture); expect( await pluginRepo.isGranted( pluginRepo.address, - deployer.address, + managementDaoProxy.address, DAO_PERMISSIONS.ROOT_PERMISSION_ID, PERMISSION_MANAGER_FLAGS.NO_CONDITION ) @@ -46,7 +48,7 @@ describe(`Deployment on network '${productionNetworkName}'`, function () { expect( await pluginRepo.isGranted( pluginRepo.address, - deployer.address, + managementDaoProxy.address, PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, PERMISSION_MANAGER_FLAGS.NO_CONDITION ) @@ -55,7 +57,7 @@ describe(`Deployment on network '${productionNetworkName}'`, function () { expect( await pluginRepo.isGranted( pluginRepo.address, - deployer.address, + managementDaoProxy.address, PLUGIN_REPO_PERMISSIONS.MAINTAINER_PERMISSION_ID, PERMISSION_MANAGER_FLAGS.NO_CONDITION ) @@ -89,16 +91,17 @@ type FixtureResult = { deployer: SignerWithAddress; pluginRepo: PluginRepo; pluginRepoRegistry: PluginRepoRegistry; + managementDaoProxy: DAO; }; async function fixture(): Promise { // Deploy all - const tags = ['CreateRepo', 'NewVersion']; - await deployments.fixture(tags); + const tags = ['CreateRepo', 'NewVersion', 'TransferOwnershipToManagmentDao']; + await deployments.fixture(tags); const [deployer] = await ethers.getSigners(); - // Plugin Repo + // Plugin repo const {pluginRepo, ensDomain} = await findPluginRepo(env); if (pluginRepo === null) { throw `PluginRepo '${ensDomain}' does not exist yet.`; @@ -119,5 +122,11 @@ async function fixture(): Promise { deployer ); - return {deployer, pluginRepo, pluginRepoRegistry}; + // Management DAO proxy + const managementDaoProxy = DAO__factory.connect( + networkDeployments.ManagementDAOProxy.address, + deployer + ); + + return {deployer, pluginRepo, pluginRepoRegistry, managementDaoProxy}; } diff --git a/packages/contracts/test/20_integration-testing/22_setup-processing.ts b/packages/contracts/test/20_integration-testing/22_setup-processing.ts index bb9da6af..3b1fc997 100644 --- a/packages/contracts/test/20_integration-testing/22_setup-processing.ts +++ b/packages/contracts/test/20_integration-testing/22_setup-processing.ts @@ -1,18 +1,20 @@ -import {METADATA} from '../../plugin-settings'; -import { - DAOMock, - DAOMock__factory, - MyPluginSetup, - MyPluginSetup__factory, - MyPlugin__factory, -} from '../../typechain'; +import {METADATA, VERSION} from '../../plugin-settings'; +import {MultisigSetup, Multisig__factory} from '../../typechain'; import {getProductionNetworkName, findPluginRepo} from '../../utils/helpers'; -import {installPLugin, uninstallPLugin} from './test-helpers'; +import {Multisig} from '../test-utils/typechain-versions'; +import { + createDaoProxy, + installPLugin, + uninstallPLugin, + updateFromBuildTest, +} from './test-helpers'; import { getLatestNetworkDeployment, getNetworkNameByAlias, } from '@aragon/osx-commons-configs'; import { + DAO_PERMISSIONS, + PLUGIN_SETUP_PROCESSOR_PERMISSIONS, UnsupportedNetworkError, getNamedTypesFromMetadata, } from '@aragon/osx-commons-sdk'; @@ -21,77 +23,29 @@ import { PluginRepo, PluginSetupProcessorStructs, PluginSetupProcessor__factory, + DAO, + MultisigSetup__factory, } from '@aragon/osx-ethers'; import {loadFixture} from '@nomicfoundation/hardhat-network-helpers'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; -import {BigNumber} from 'ethers'; import env, {deployments, ethers} from 'hardhat'; const productionNetworkName = getProductionNetworkName(env); -describe(`PluginSetup processing on network '${productionNetworkName}'`, function () { - it('installs & uninstalls the current build', async () => { - const {deployer, psp, daoMock, pluginSetup, pluginSetupRef} = - await loadFixture(fixture); - - // Allow all authorized calls to happen - await daoMock.setHasPermissionReturnValueMock(true); - - // Install the current build. - const results = await installPLugin( - deployer, - psp, - daoMock, - pluginSetupRef, - ethers.utils.defaultAbiCoder.encode( - getNamedTypesFromMetadata( - METADATA.build.pluginSetup.prepareInstallation.inputs - ), - [123] - ) - ); - - const plugin = MyPlugin__factory.connect( - results.preparedEvent.args.plugin, - deployer - ); - - // Check implementation. - expect(await plugin.implementation()).to.be.eq( - await pluginSetup.implementation() - ); - - // Check state. - expect(await plugin.number()).to.eq(123); - - // Uninstall the current build. - await uninstallPLugin( - deployer, - psp, - daoMock, - plugin, - pluginSetupRef, - ethers.utils.defaultAbiCoder.encode( - getNamedTypesFromMetadata( - METADATA.build.pluginSetup.prepareUninstallation.inputs - ), - [] - ), - [] - ); - }); -}); - type FixtureResult = { deployer: SignerWithAddress; alice: SignerWithAddress; bob: SignerWithAddress; - daoMock: DAOMock; + dao: DAO; + defaultInitData: { + members: string[]; + settings: Multisig.MultisigSettingsStruct; + }; psp: PluginSetupProcessor; pluginRepo: PluginRepo; - pluginSetup: MyPluginSetup; - pluginSetupRef: PluginSetupProcessorStructs.PluginSetupRefStruct; + pluginSetup: MultisigSetup; + pluginSetupRefLatestBuild: PluginSetupProcessorStructs.PluginSetupRefStruct; }; async function fixture(): Promise { @@ -100,7 +54,10 @@ async function fixture(): Promise { await deployments.fixture(tags); const [deployer, alice, bob] = await ethers.getSigners(); - const daoMock = await new DAOMock__factory(deployer).deploy(); + const dummyMetadata = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes('0x123456789') + ); + const dao = await createDaoProxy(deployer, dummyMetadata); const network = getNetworkNameByAlias(productionNetworkName); if (network === null) { @@ -124,15 +81,23 @@ async function fixture(): Promise { } const release = 1; - const pluginSetup = MyPluginSetup__factory.connect( + const pluginSetup = MultisigSetup__factory.connect( (await pluginRepo['getLatestVersion(uint8)'](release)).pluginSetup, deployer ); - const pluginSetupRef = { + const defaultInitData = { + members: [alice.address], + settings: { + onlyListed: true, + minApprovals: 1, + }, + }; + + const pluginSetupRefLatestBuild = { versionTag: { - release: BigNumber.from(1), - build: BigNumber.from(1), + release: VERSION.release, + build: VERSION.build, }, pluginSetupRepo: pluginRepo.address, }; @@ -142,9 +107,124 @@ async function fixture(): Promise { alice, bob, psp, - daoMock, + dao, + defaultInitData, pluginRepo, pluginSetup, - pluginSetupRef, + pluginSetupRefLatestBuild, }; } + +describe(`PluginSetup processing on network '${productionNetworkName}'`, function () { + it('installs & uninstalls the current build', async () => { + const {alice, bob, deployer, psp, dao, pluginSetupRefLatestBuild} = + await loadFixture(fixture); + + // Grant deployer all required permissions + await dao + .connect(deployer) + .grant( + psp.address, + deployer.address, + PLUGIN_SETUP_PROCESSOR_PERMISSIONS.APPLY_INSTALLATION_PERMISSION_ID + ); + await dao + .connect(deployer) + .grant( + psp.address, + deployer.address, + PLUGIN_SETUP_PROCESSOR_PERMISSIONS.APPLY_UNINSTALLATION_PERMISSION_ID + ); + await dao + .connect(deployer) + .grant(dao.address, psp.address, DAO_PERMISSIONS.ROOT_PERMISSION_ID); + + // Install the current build. + const initialMembers = [alice.address, bob.address]; + const multisigSettings: Multisig.MultisigSettingsStruct = { + onlyListed: true, + minApprovals: 2, + }; + + const results = await installPLugin( + deployer, + psp, + dao, + pluginSetupRefLatestBuild, + ethers.utils.defaultAbiCoder.encode( + getNamedTypesFromMetadata( + METADATA.build.pluginSetup.prepareInstallation.inputs + ), + [initialMembers, multisigSettings] + ) + ); + + const plugin = Multisig__factory.connect( + results.preparedEvent.args.plugin, + deployer + ); + + // Check that the setup worked + expect(await plugin.isMember(alice.address)).to.be.true; + + // Uninstall the current build. + await uninstallPLugin( + deployer, + psp, + dao, + plugin, + pluginSetupRefLatestBuild, + ethers.utils.defaultAbiCoder.encode( + getNamedTypesFromMetadata( + METADATA.build.pluginSetup.prepareUninstallation.inputs + ), + [] + ), + [] + ); + }); + + it('updates from build 1 to the current build', async () => { + const { + deployer, + psp, + dao, + defaultInitData, + pluginRepo, + pluginSetupRefLatestBuild, + } = await loadFixture(fixture); + + await updateFromBuildTest( + dao, + deployer, + psp, + pluginRepo, + pluginSetupRefLatestBuild, + 1, + [defaultInitData.members, Object.values(defaultInitData.settings)], + [] + ); + }); + + it('updates from build 2 to the current build', async () => { + const { + deployer, + psp, + dao, + defaultInitData, + pluginRepo, + pluginSetupRefLatestBuild, + } = await loadFixture(fixture); + + await updateFromBuildTest( + dao, + deployer, + psp, + pluginRepo, + pluginSetupRefLatestBuild, + 2, + [defaultInitData.members, Object.values(defaultInitData.settings)], + [] + ); + }); +}); diff --git a/packages/contracts/test/20_integration-testing/test-helpers.ts b/packages/contracts/test/20_integration-testing/test-helpers.ts index a8712834..bfbf2046 100644 --- a/packages/contracts/test/20_integration-testing/test-helpers.ts +++ b/packages/contracts/test/20_integration-testing/test-helpers.ts @@ -1,24 +1,37 @@ -import {DAOMock, IPlugin} from '../../typechain'; +import {METADATA, VERSION} from '../../plugin-settings'; +import { + IPlugin, + PluginUpgradeableSetup__factory, + ProxyFactory__factory, +} from '../../typechain'; +import {ProxyCreatedEvent} from '../../typechain/@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory'; +import {PluginUUPSUpgradeable__factory} from '../../typechain/factories/@aragon/osx-v1.0.0/core/plugin'; import {hashHelpers} from '../../utils/helpers'; import { DAO_PERMISSIONS, PLUGIN_SETUP_PROCESSOR_PERMISSIONS, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS, findEvent, + getNamedTypesFromMetadata, } from '@aragon/osx-commons-sdk'; import { PluginSetupProcessorEvents, PluginSetupProcessorStructs, PluginSetupProcessor, DAOStructs, + DAO, + DAO__factory, + PluginRepo, } from '@aragon/osx-ethers'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {ContractTransaction} from 'ethers'; +import {ethers} from 'hardhat'; export async function installPLugin( signer: SignerWithAddress, psp: PluginSetupProcessor, - dao: DAOMock, + dao: DAO, pluginSetupRef: PluginSetupProcessorStructs.PluginSetupRefStruct, data: string ): Promise<{ @@ -68,7 +81,7 @@ export async function installPLugin( export async function uninstallPLugin( signer: SignerWithAddress, psp: PluginSetupProcessor, - dao: DAOMock, + dao: DAO, plugin: IPlugin, pluginSetupRef: PluginSetupProcessorStructs.PluginSetupRefStruct, data: string, @@ -123,7 +136,7 @@ export async function uninstallPLugin( export async function updatePlugin( signer: SignerWithAddress, psp: PluginSetupProcessor, - dao: DAOMock, + dao: DAO, plugin: IPlugin, currentHelpers: string[], pluginSetupRefCurrent: PluginSetupProcessorStructs.PluginSetupRefStruct, @@ -183,7 +196,7 @@ export async function updatePlugin( async function checkPermissions( preparedPermissions: DAOStructs.MultiTargetPermissionStruct[], - dao: DAOMock, + dao: DAO, psp: PluginSetupProcessor, signer: SignerWithAddress, applyPermissionId: string @@ -212,3 +225,140 @@ async function checkPermissions( throw `The used signer does not have the permission with ID '${applyPermissionId}' granted and thus cannot apply the setup`; } } + +export async function updateFromBuildTest( + dao: DAO, + deployer: SignerWithAddress, + psp: PluginSetupProcessor, + pluginRepo: PluginRepo, + pluginSetupRefLatestBuild: PluginSetupProcessorStructs.PluginSetupRefStruct, + build: number, + installationInputs: any[], + updateInputs: any[] +) { + // Grant deployer all required permissions + await dao + .connect(deployer) + .grant( + psp.address, + deployer.address, + PLUGIN_SETUP_PROCESSOR_PERMISSIONS.APPLY_INSTALLATION_PERMISSION_ID + ); + await dao + .connect(deployer) + .grant( + psp.address, + deployer.address, + PLUGIN_SETUP_PROCESSOR_PERMISSIONS.APPLY_UPDATE_PERMISSION_ID + ); + + await dao + .connect(deployer) + .grant(dao.address, psp.address, DAO_PERMISSIONS.ROOT_PERMISSION_ID); + + // Install build 1. + const pluginSetupRefBuild1 = { + versionTag: { + release: VERSION.release, + build: build, + }, + pluginSetupRepo: pluginRepo.address, + }; + const installationResults = await installPLugin( + deployer, + psp, + dao, + pluginSetupRefBuild1, + ethers.utils.defaultAbiCoder.encode( + getNamedTypesFromMetadata( + METADATA.build.pluginSetup.prepareInstallation.inputs + ), + installationInputs + ) + ); + + // Get the plugin address. + const plugin = PluginUUPSUpgradeable__factory.connect( + installationResults.preparedEvent.args.plugin, + deployer + ); + + // Check that the implementation of the plugin proxy matches the latest build + const implementationBuild1 = await PluginUpgradeableSetup__factory.connect( + ( + await pluginRepo['getVersion((uint8,uint16))']( + pluginSetupRefBuild1.versionTag + ) + ).pluginSetup, + deployer + ).implementation(); + expect(await plugin.implementation()).to.equal(implementationBuild1); + + // Grant the PSP the permission to upgrade the plugin implementation. + await dao + .connect(deployer) + .grant( + plugin.address, + psp.address, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS.UPGRADE_PLUGIN_PERMISSION_ID + ); + + // Update build 1 to the latest build + await expect( + updatePlugin( + deployer, + psp, + dao, + plugin, + installationResults.preparedEvent.args.preparedSetupData.helpers, + pluginSetupRefBuild1, + pluginSetupRefLatestBuild, + ethers.utils.defaultAbiCoder.encode( + getNamedTypesFromMetadata( + METADATA.build.pluginSetup.prepareUpdate[1].inputs + ), + updateInputs + ) + ) + ).to.not.be.reverted; + + // Check that the implementation of the plugin proxy matches the latest build + const implementationLatestBuild = + await PluginUpgradeableSetup__factory.connect( + ( + await pluginRepo['getVersion((uint8,uint16))']( + pluginSetupRefLatestBuild.versionTag + ) + ).pluginSetup, + deployer + ).implementation(); + expect(await plugin.implementation()).to.equal(implementationLatestBuild); +} + +// TODO Move into OSX commons as part of Task OS-928. +export async function createDaoProxy( + deployer: SignerWithAddress, + dummyMetadata: string +): Promise { + const daoImplementation = await new DAO__factory(deployer).deploy(); + const daoProxyFactory = await new ProxyFactory__factory(deployer).deploy( + daoImplementation.address + ); + + const daoInitData = daoImplementation.interface.encodeFunctionData( + 'initialize', + [ + dummyMetadata, + deployer.address, + ethers.constants.AddressZero, + dummyMetadata, + ] + ); + const tx = await daoProxyFactory.deployUUPSProxy(daoInitData); + const event = await findEvent( + tx, + daoProxyFactory.interface.getEvent('ProxyCreated').name + ); + const dao = DAO__factory.connect(event.args.proxy, deployer); + return dao; +} diff --git a/packages/contracts/test/30_regression-testing/31_upgradeability.ts b/packages/contracts/test/30_regression-testing/31_upgradeability.ts new file mode 100644 index 00000000..4d57b5c5 --- /dev/null +++ b/packages/contracts/test/30_regression-testing/31_upgradeability.ts @@ -0,0 +1,135 @@ +import {createDaoProxy} from '../20_integration-testing/test-helpers'; +import { + Multisig_V1_1__factory, + Multisig_V1_2__factory, + Multisig__factory, + Multisig, +} from '../test-utils/typechain-versions'; +import { + deployAndUpgradeFromToCheck, + deployAndUpgradeSelfCheck, + getProtocolVersion, +} from '../test-utils/uups-upgradeable'; +import {PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS} from '@aragon/osx-commons-sdk'; +import {DAO} from '@aragon/osx-ethers'; +import {loadFixture} from '@nomicfoundation/hardhat-network-helpers'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; +import {expect} from 'chai'; +import {ethers} from 'hardhat'; + +describe('Upgrades', () => { + it('upgrades to a new implementation', async () => { + const {deployer, alice, dao, defaultInitData} = await loadFixture(fixture); + const currentContractFactory = new Multisig__factory(deployer); + + await deployAndUpgradeSelfCheck( + deployer, + alice, + [dao.address, defaultInitData.members, defaultInitData.settings], + 'initialize', + currentContractFactory, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS.UPGRADE_PLUGIN_PERMISSION_ID, + dao + ); + }); + + it('upgrades from v1.1', async () => { + const {deployer, alice, dao, defaultInitData} = await loadFixture(fixture); + const currentContractFactory = new Multisig__factory(deployer); + const legacyContractFactory = new Multisig_V1_1__factory(deployer); + + const {fromImplementation, toImplementation} = + await deployAndUpgradeFromToCheck( + deployer, + alice, + [dao.address, defaultInitData.members, defaultInitData.settings], + 'initialize', + legacyContractFactory, + currentContractFactory, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS.UPGRADE_PLUGIN_PERMISSION_ID, + dao + ); + expect(toImplementation).to.not.equal(fromImplementation); // The build did change + + const fromProtocolVersion = await getProtocolVersion( + legacyContractFactory.attach(fromImplementation) + ); + const toProtocolVersion = await getProtocolVersion( + currentContractFactory.attach(toImplementation) + ); + + expect(fromProtocolVersion).to.not.deep.equal(toProtocolVersion); + expect(fromProtocolVersion).to.deep.equal([1, 0, 0]); + expect(toProtocolVersion).to.deep.equal([1, 4, 0]); + }); + + it('from v1.2', async () => { + const {deployer, alice, dao, defaultInitData} = await loadFixture(fixture); + const currentContractFactory = new Multisig__factory(deployer); + const legacyContractFactory = new Multisig_V1_2__factory(deployer); + + const {fromImplementation, toImplementation} = + await deployAndUpgradeFromToCheck( + deployer, + alice, + [dao.address, defaultInitData.members, defaultInitData.settings], + 'initialize', + legacyContractFactory, + currentContractFactory, + PLUGIN_UUPS_UPGRADEABLE_PERMISSIONS.UPGRADE_PLUGIN_PERMISSION_ID, + dao + ); + expect(toImplementation).to.not.equal(fromImplementation); + + const fromProtocolVersion = await getProtocolVersion( + legacyContractFactory.attach(fromImplementation) + ); + const toProtocolVersion = await getProtocolVersion( + currentContractFactory.attach(toImplementation) + ); + + expect(fromProtocolVersion).to.not.deep.equal(toProtocolVersion); + expect(fromProtocolVersion).to.deep.equal([1, 0, 0]); + expect(toProtocolVersion).to.deep.equal([1, 4, 0]); + }); +}); + +type FixtureResult = { + deployer: SignerWithAddress; + alice: SignerWithAddress; + bob: SignerWithAddress; + carol: SignerWithAddress; + defaultInitData: { + members: string[]; + settings: Multisig.MultisigSettingsStruct; + }; + dao: DAO; +}; + +async function fixture(): Promise { + const [deployer, alice, bob, carol] = await ethers.getSigners(); + + const dummyMetadata = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes('0x123456789') + ); + + const dao = await createDaoProxy(deployer, dummyMetadata); + + // Create an initialized plugin clone + const defaultInitData = { + members: [alice.address, bob.address, carol.address], + settings: { + onlyListed: true, + minApprovals: 2, + }, + }; + + return { + deployer, + alice, + bob, + carol, + dao, + defaultInitData, + }; +} diff --git a/packages/contracts/test/multisig-constants.ts b/packages/contracts/test/multisig-constants.ts new file mode 100644 index 00000000..d9e55641 --- /dev/null +++ b/packages/contracts/test/multisig-constants.ts @@ -0,0 +1,17 @@ +import {ethers} from 'hardhat'; + +export const MULTISIG_EVENTS = { + MultisigSettingsUpdated: 'MultisigSettingsUpdated', + Approved: 'Approved', +}; + +export const MULTISIG_INTERFACE = new ethers.utils.Interface([ + 'function initialize(address,address[],tuple(bool,uint16))', + 'function updateMultisigSettings(tuple(bool,uint16))', + 'function createProposal(bytes,tuple(address,uint256,bytes)[],uint256,bool,bool,uint64,uint64) ', + 'function getProposal(uint256)', +]); + +export const UPDATE_MULTISIG_SETTINGS_PERMISSION_ID = ethers.utils.id( + 'UPDATE_MULTISIG_SETTINGS_PERMISSION' +); diff --git a/packages/contracts/test/test-utils/typechain-versions.ts b/packages/contracts/test/test-utils/typechain-versions.ts new file mode 100644 index 00000000..34988e62 --- /dev/null +++ b/packages/contracts/test/test-utils/typechain-versions.ts @@ -0,0 +1,9 @@ +/// Typechain will sometimes by default link to the wrong version of the contract, when we have name collisions +/// The version specified in src is the factory and contract without the version number. +/// Import as needed in the test files, and use the correct version of the contract. + +export {Multisig__factory as Multisig_V1_1__factory} from '../../typechain/factories/@aragon/osx-v1.0.0/plugins/governance/multisig/Multisig__factory'; +export {Multisig__factory as Multisig_V1_2__factory} from '../../typechain/factories/@aragon/osx-v1.3.0/plugins/governance/multisig/Multisig__factory'; +export {Multisig__factory} from '../../typechain/factories/src/Multisig__factory'; +export {Multisig} from '../../typechain/src/Multisig'; +export {IMultisig} from '../../typechain/src/IMultisig'; diff --git a/packages/contracts/test/test-utils/uups-upgradeable.ts b/packages/contracts/test/test-utils/uups-upgradeable.ts new file mode 100644 index 00000000..80183815 --- /dev/null +++ b/packages/contracts/test/test-utils/uups-upgradeable.ts @@ -0,0 +1,189 @@ +import {DAO, PluginRepo} from '@aragon/osx-ethers'; +import {defaultAbiCoder} from '@ethersproject/abi'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; +import {expect} from 'chai'; +import {Contract, ContractFactory, errors} from 'ethers'; +import {ethers, upgrades} from 'hardhat'; + +// The protocol version number of contracts not having a `getProtocolVersion()` function because they don't inherit from `ProtocolVersion.sol` yet. +export const IMPLICIT_INITIAL_PROTOCOL_VERSION: [number, number, number] = [ + 1, 0, 0, +]; + +// See https://eips.ethereum.org/EIPS/eip-1967 +export const ERC1967_IMPLEMENTATION_SLOT = + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) + +export const OZ_INITIALIZED_SLOT_POSITION = 0; + +// Deploys a proxy and a new implementation from the same factory and checks that the upgrade works. +export async function deployAndUpgradeSelfCheck( + deployer: SignerWithAddress, + upgrader: SignerWithAddress, + initArgs: any, + initializerName: string, + factory: ContractFactory, + upgradePermissionId: string, + managingContract?: DAO | PluginRepo | undefined +) { + // Deploy proxy and implementation + const proxy = await upgrades.deployProxy( + factory.connect(deployer), + Object.values(initArgs), + { + kind: 'uups', + initializer: initializerName, + unsafeAllow: ['constructor'], + constructorArgs: [], + } + ); + + // Grant the upgrade permission + const grantArgs: [string, string, string] = [ + proxy.address, + upgrader.address, + upgradePermissionId, + ]; + + // Check if the contract is a permission manager itself + if (managingContract === undefined) { + await expect( + upgrades.upgradeProxy(proxy.address, factory.connect(upgrader), { + unsafeAllow: ['constructor'], + constructorArgs: [], + }) + ) + .to.be.revertedWithCustomError(proxy, 'Unauthorized') + .withArgs(...grantArgs); + + await proxy.connect(deployer).grant(...grantArgs); + } + // Or if the permission manager is located in a different contract + else { + await expect( + upgrades.upgradeProxy(proxy.address, factory.connect(upgrader), { + unsafeAllow: ['constructor'], + constructorArgs: [], + }) + ) + .to.be.revertedWithCustomError(proxy, 'DaoUnauthorized') + .withArgs(managingContract.address, ...grantArgs); + + await managingContract.connect(deployer).grant(...grantArgs); + } + + // Deploy a new implementation (the same contract at a different address) + const toImplementation = (await factory.deploy()).address; + + // Confirm that the two implementations are different + + const fromImplementation = await ethers.provider + .getStorageAt(proxy.address, ERC1967_IMPLEMENTATION_SLOT) + .then(encoded => defaultAbiCoder.decode(['address'], encoded)[0]); + + expect(toImplementation).to.not.equal(fromImplementation); + + // Upgrade from the old to the new implementation + await proxy.connect(upgrader).upgradeTo(toImplementation); + + // Confirm that the proxy points to the new implementation + const implementationAfterUpgrade = await ethers.provider + .getStorageAt(proxy.address, ERC1967_IMPLEMENTATION_SLOT) + .then(encoded => defaultAbiCoder.decode(['address'], encoded)[0]); + expect(implementationAfterUpgrade).to.equal(toImplementation); +} + +// Deploys a proxy and a new implementation via two different factories and checks that the upgrade works. +export async function deployAndUpgradeFromToCheck( + deployer: SignerWithAddress, + upgrader: SignerWithAddress, + initArgs: any, + initializerName: string, + from: ContractFactory, + to: ContractFactory, + upgradePermissionId: string, + managingDao?: DAO | PluginRepo +): Promise<{ + proxy: Contract; + fromImplementation: string; + toImplementation: string; +}> { + // Deploy proxy and implementation + const proxy = await upgrades.deployProxy( + from.connect(deployer), + Object.values(initArgs), + { + kind: 'uups', + initializer: initializerName, + unsafeAllow: ['constructor'], + constructorArgs: [], + } + ); + + const fromImplementation = await ethers.provider + .getStorageAt(proxy.address, ERC1967_IMPLEMENTATION_SLOT) + .then(encoded => defaultAbiCoder.decode(['address'], encoded)[0]); + + // Grant the upgrade permission + const grantArgs: [string, string, string] = [ + proxy.address, + upgrader.address, + upgradePermissionId, + ]; + + if (managingDao === undefined) { + await expect( + upgrades.upgradeProxy(proxy.address, to.connect(upgrader), { + unsafeAllow: ['constructor'], + constructorArgs: [], + }) + ) + .to.be.revertedWithCustomError(proxy, 'Unauthorized') + .withArgs(...grantArgs); + + await proxy.connect(deployer).grant(...grantArgs); + } else { + await expect( + upgrades.upgradeProxy(proxy.address, to.connect(upgrader), { + unsafeAllow: ['constructor'], + constructorArgs: [], + }) + ) + .to.be.revertedWithCustomError(proxy, 'DaoUnauthorized') + .withArgs(managingDao.address, ...grantArgs); + + await managingDao.connect(deployer).grant(...grantArgs); + } + + // Upgrade the proxy to a new implementation from a different factory + await upgrades.upgradeProxy(proxy.address, to.connect(upgrader), { + unsafeAllow: ['constructor'], + constructorArgs: [], + }); + + const toImplementation = await ethers.provider + .getStorageAt(proxy.address, ERC1967_IMPLEMENTATION_SLOT) + .then(encoded => defaultAbiCoder.decode(['address'], encoded)[0]); + return {proxy, fromImplementation, toImplementation}; +} + +export async function getProtocolVersion( + contract: Contract +): Promise<[number, number, number]> { + let protocolVersion: [number, number, number]; + try { + contract.interface.getFunction('protocolVersion'); + protocolVersion = await contract.protocolVersion(); + } catch (error: unknown) { + if ( + error instanceof Error && + 'code' in error && + error.code === errors.INVALID_ARGUMENT + ) { + protocolVersion = IMPLICIT_INITIAL_PROTOCOL_VERSION; + } else { + throw error; + } + } + return protocolVersion; +} diff --git a/packages/contracts/utils/helpers.ts b/packages/contracts/utils/helpers.ts index c76f6992..6b13eb8d 100644 --- a/packages/contracts/utils/helpers.ts +++ b/packages/contracts/utils/helpers.ts @@ -10,6 +10,8 @@ import { findEvent, } from '@aragon/osx-commons-sdk'; import { + DAO, + DAO__factory, ENSSubdomainRegistrar__factory, ENS__factory, IAddrResolver__factory, @@ -17,7 +19,9 @@ import { PluginRepoEvents, PluginRepo__factory, } from '@aragon/osx-ethers'; -import {ContractTransaction} from 'ethers'; +import {setBalance} from '@nomicfoundation/hardhat-network-helpers'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; +import {BigNumber, ContractTransaction} from 'ethers'; import {LogDescription, defaultAbiCoder, keccak256} from 'ethers/lib/utils'; import {ethers} from 'hardhat'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; @@ -68,6 +72,7 @@ export async function findPluginRepo( ): Promise<{pluginRepo: PluginRepo | null; ensDomain: string}> { const [deployer] = await hre.ethers.getSigners(); const productionNetworkName: string = getProductionNetworkName(hre); + const network = getNetworkNameByAlias(productionNetworkName); if (network === null) { throw new UnsupportedNetworkError(productionNetworkName); @@ -107,6 +112,61 @@ export async function findPluginRepo( } } +export async function getManagementDao( + hre: HardhatRuntimeEnvironment +): Promise { + const [deployer] = await hre.ethers.getSigners(); + const productionNetworkName = getProductionNetworkName(hre); + const network = getNetworkNameByAlias(productionNetworkName); + if (network === null) { + throw new UnsupportedNetworkError(productionNetworkName); + } + const networkDeployments = getLatestNetworkDeployment(network); + if (networkDeployments === null) { + throw `Deployments are not available on network ${network}.`; + } + + return DAO__factory.connect( + networkDeployments.ManagementDAOProxy.address, + deployer + ); +} + +export async function getManagementDaoMultisig( + hre: HardhatRuntimeEnvironment +): Promise { + const [deployer] = await hre.ethers.getSigners(); + const productionNetworkName = getProductionNetworkName(hre); + const network = getNetworkNameByAlias(productionNetworkName); + if (network === null) { + throw new UnsupportedNetworkError(productionNetworkName); + } + const networkDeployments = getLatestNetworkDeployment(network); + if (networkDeployments === null) { + throw `Deployments are not available on network ${network}.`; + } + + return DAO__factory.connect( + networkDeployments.ManagementDAOProxy.address, + deployer + ); +} + +export async function impersonatedManagementDaoSigner( + hre: HardhatRuntimeEnvironment +): Promise { + return await (async () => { + const managementDaoProxy = getManagementDao(hre); + const signer = await hre.ethers.getImpersonatedSigner( + ( + await managementDaoProxy + ).address + ); + await setBalance(signer.address, BigNumber.from(10).pow(18)); + return signer; + })(); +} + export type EventWithBlockNumber = { event: LogDescription; blockNumber: number; diff --git a/packages/contracts/yarn.lock b/packages/contracts/yarn.lock index 43944771..1a23906f 100644 --- a/packages/contracts/yarn.lock +++ b/packages/contracts/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@aragon/osx-artifacts@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@aragon/osx-artifacts/-/osx-artifacts-1.3.1.tgz#68fa04844086a92d74351df2e9392ade3c8696dc" - integrity sha512-u6IFP8fQZIS65Ks5Sl1DKlw8Qp9s5I7DSn9n/odQohWnN65A17HwHaCPTEcXl2AL3r71rFawldQ8i5/2yU3UGA== - "@aragon/osx-commons-configs@0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@aragon/osx-commons-configs/-/osx-commons-configs-0.1.0.tgz#21bbc5a964eb144e30033a44cc352d35c62982f9" @@ -63,6 +58,20 @@ dependencies: ethers "^5.6.2" +"@aragon/osx-v1.0.0@npm:@aragon/osx@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@aragon/osx/-/osx-1.0.1.tgz#b758ba87db93a46a8ddabfaefc99ac8e44c46c78" + integrity sha512-TiP5/1AGv/hth+V8PoDVFlwMzmLazYxzp//jiepAZ0WJkx9EnQNYafo+M7+pjAqRPG005liQjmFZNiK6ARLULg== + +"@aragon/osx-v1.3.0@npm:@aragon/osx@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@aragon/osx/-/osx-1.3.0.tgz#eee59963546016bb3b41b7c7a9b7c41d33b37de2" + integrity sha512-ziLmnhWEoFS/uthxAYfI9tSylesMLTDe69XggKP9LK/tIOKAhyYjfAJ2mbhWZcH558c9o0gzAEErkDhqh/wdog== + dependencies: + "@ensdomains/ens-contracts" "0.0.11" + "@openzeppelin/contracts" "4.8.1" + "@openzeppelin/contracts-upgradeable" "4.8.1" + "@aragon/sdk-ipfs@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@aragon/sdk-ipfs/-/sdk-ipfs-1.1.0.tgz#178ee5ce840ce40b44ba0345dd5068e1b5608f9d" @@ -106,6 +115,13 @@ dependencies: tslib "^2.3.1" +"@babel/runtime@^7.4.4": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" + integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== + dependencies: + regenerator-runtime "^0.14.0" + "@chainsafe/as-sha256@^0.3.1": version "0.3.1" resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" @@ -149,11 +165,110 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@ensdomains/address-encoder@^0.1.7": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d" + integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg== + dependencies: + bech32 "^1.1.3" + blakejs "^1.1.0" + bn.js "^4.11.8" + bs58 "^4.0.1" + crypto-addr-codec "^0.1.7" + nano-base32 "^1.0.1" + ripemd160 "^2.0.2" + +"@ensdomains/buffer@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@ensdomains/buffer/-/buffer-0.0.13.tgz#b9f60defb78fc5f2bee30faca17e63dfbef19253" + integrity sha512-8aA+U/e4S54ebPwcge1HHvvpgXLKxPd6EOSegMlrTvBnKB8RwB3OpNyflaikD6KqzIwDaBaH8bvnTrMcfpV7oQ== + dependencies: + "@nomiclabs/hardhat-truffle5" "^2.0.0" + +"@ensdomains/ens-contracts@0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@ensdomains/ens-contracts/-/ens-contracts-0.0.11.tgz#a1cd87af8c454b694acba5be1a44c1b20656a9be" + integrity sha512-b74OlFcds9eyHy26uE2fGcM+ZCSFtPeRGVbUYWq3NRlf+9t8TIgPwF3rCNwpAFQG0B/AHb4C4hYX2BBJYR1zPg== + dependencies: + "@ensdomains/buffer" "^0.0.13" + "@ensdomains/solsha1" "0.0.3" + "@openzeppelin/contracts" "^4.1.0" + dns-packet "^5.3.0" + +"@ensdomains/ens@0.4.5": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + +"@ensdomains/ensjs@^2.0.1": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460" + integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog== + dependencies: + "@babel/runtime" "^7.4.4" + "@ensdomains/address-encoder" "^0.1.7" + "@ensdomains/ens" "0.4.5" + "@ensdomains/resolver" "0.2.4" + content-hash "^2.5.2" + eth-ens-namehash "^2.0.8" + ethers "^5.0.13" + js-sha3 "^0.8.0" + +"@ensdomains/resolver@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" + integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== + +"@ensdomains/solsha1@0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@ensdomains/solsha1/-/solsha1-0.0.3.tgz#fd479da9d40aadb59ff4fb4ec50632e7d2275a83" + integrity sha512-uhuG5LzRt/UJC0Ux83cE2rCKwSleRePoYdQVcqPN1wyf3/ekMzT/KZUF9+v7/AG5w9jlMLCQkUM50vfjr0Yu9Q== + dependencies: + hash-test-vectors "^1.3.2" + +"@ethereumjs/common@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268" + integrity sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.1" + +"@ethereumjs/common@2.6.5", "@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.4": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" + integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.5" + "@ethereumjs/rlp@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== +"@ethereumjs/tx@3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.2.tgz#348d4624bf248aaab6c44fec2ae67265efe3db00" + integrity sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog== + dependencies: + "@ethereumjs/common" "^2.5.0" + ethereumjs-util "^7.1.2" + +"@ethereumjs/tx@3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c" + integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw== + dependencies: + "@ethereumjs/common" "^2.6.4" + ethereumjs-util "^7.1.5" + "@ethereumjs/util@^8.1.0": version "8.1.0" resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" @@ -438,7 +553,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== @@ -555,6 +670,11 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + "@metamask/eth-sig-util@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" @@ -858,12 +978,49 @@ table "^6.8.0" undici "^5.14.0" +"@nomiclabs/hardhat-truffle5@^2.0.0": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.7.tgz#7519eadd2c6c460c2addc3d4d6efda7a8883361e" + integrity sha512-Pw8451IUZp1bTp0QqCHCYfCHs66sCnyxPcaorapu9mfOV9xnZsVaFdtutnhNEiXdiZwbed7LFKpRsde4BjFwig== + dependencies: + "@nomiclabs/truffle-contract" "^4.2.23" + "@types/chai" "^4.2.0" + chai "^4.2.0" + ethereumjs-util "^7.1.4" + fs-extra "^7.0.1" + +"@nomiclabs/truffle-contract@^4.2.23": + version "4.5.10" + resolved "https://registry.yarnpkg.com/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz#52adcca1068647e1c2b44bf0e6a89fc4ad7f9213" + integrity sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ== + dependencies: + "@ensdomains/ensjs" "^2.0.1" + "@truffle/blockchain-utils" "^0.1.3" + "@truffle/contract-schema" "^3.4.7" + "@truffle/debug-utils" "^6.0.22" + "@truffle/error" "^0.1.0" + "@truffle/interface-adapter" "^0.5.16" + bignumber.js "^7.2.1" + ethereum-ens "^0.8.0" + ethers "^4.0.0-beta.1" + source-map-support "^0.5.19" + +"@openzeppelin/contracts-upgradeable@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.1.tgz#363f7dd08f25f8f77e16d374350c3d6b43340a7a" + integrity sha512-1wTv+20lNiC0R07jyIAbHU7TNHKRwGiTGRfiNnA8jOWjKT98g5OgLpYWOi40Vgpk8SPLA9EvfJAbAeIyVn+7Bw== + "@openzeppelin/contracts-upgradeable@4.9.5", "@openzeppelin/contracts-upgradeable@^4.9.5": version "4.9.5" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.5.tgz#572b5da102fc9be1d73f34968e0ca56765969812" integrity sha512-f7L1//4sLlflAN7fVzJLoRedrf5Na3Oal5PZfIq55NFcVZ90EpV1q5xOvL4lFvg3MNICSDr2hH0JUBxwlxcoPg== -"@openzeppelin/contracts@4.9.5", "@openzeppelin/contracts@^4.9.5": +"@openzeppelin/contracts@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.1.tgz#709cfc4bbb3ca9f4460d60101f15dac6b7a2d5e4" + integrity sha512-xQ6eUZl+RDyb/FiZe1h+U7qr/f4p/SrTSQcTPH2bjur3C5DbuW/zFgCU/b1P/xcIaEqJep+9ju4xDRi3rmChdQ== + +"@openzeppelin/contracts@4.9.5", "@openzeppelin/contracts@^4.1.0", "@openzeppelin/contracts@^4.9.5": version "4.9.5" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.5.tgz#1eed23d4844c861a1835b5d33507c1017fa98de8" integrity sha512-ZK+W5mVhRppff9BE6YdR8CC52C8zAvsVAiWhEtQ5+oNxFE6h1WdeWo+FJSF8KKvtxxVYZ7MTP/5KoVpAU3aSWg== @@ -1081,6 +1238,11 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + "@smithy/types@^2.7.0": version "2.7.0" resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.7.0.tgz#6ed9ba5bff7c4d28c980cff967e6d8456840a4f3" @@ -1102,6 +1264,111 @@ dependencies: antlr4ts "^0.5.0-alpha.4" +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + +"@truffle/abi-utils@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-1.0.3.tgz#9f0df7a8aaf5e815bee47e0ad26bd4c91e4045f2" + integrity sha512-AWhs01HCShaVKjml7Z4AbVREr/u4oiWxCcoR7Cktm0mEvtT04pvnxW5xB/cI4znRkrbPdFQlFt67kgrAjesYkw== + dependencies: + change-case "3.0.2" + fast-check "3.1.1" + web3-utils "1.10.0" + +"@truffle/blockchain-utils@^0.1.3": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.1.9.tgz#d9b55bd23a134578e4217bae55a6dfbbb038d6dc" + integrity sha512-RHfumgbIVo68Rv9ofDYfynjnYZIfP/f1vZy4RoqkfYAO+fqfc58PDRzB1WAGq2U6GPuOnipOJxQhnqNnffORZg== + +"@truffle/codec@^0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.17.3.tgz#94057e56e1a947594b35eba498d96915df3861d2" + integrity sha512-Ko/+dsnntNyrJa57jUD9u4qx9nQby+H4GsUO6yjiCPSX0TQnEHK08XWqBSg0WdmCH2+h0y1nr2CXSx8gbZapxg== + dependencies: + "@truffle/abi-utils" "^1.0.3" + "@truffle/compile-common" "^0.9.8" + big.js "^6.0.3" + bn.js "^5.1.3" + cbor "^5.2.0" + debug "^4.3.1" + lodash "^4.17.21" + semver "^7.5.4" + utf8 "^3.0.0" + web3-utils "1.10.0" + +"@truffle/compile-common@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.9.8.tgz#f91507c895852289a17bf401eefebc293c4c69f0" + integrity sha512-DTpiyo32t/YhLI1spn84D3MHYHrnoVqO+Gp7ZHrYNwDs86mAxtNiH5lsVzSb8cPgiqlvNsRCU9nm9R0YmKMTBQ== + dependencies: + "@truffle/error" "^0.2.2" + colors "1.4.0" + +"@truffle/contract-schema@^3.4.7": + version "3.4.16" + resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.4.16.tgz#c529c3f230db407b2f03290373b20b7366f2d37e" + integrity sha512-g0WNYR/J327DqtJPI70ubS19K1Fth/1wxt2jFqLsPmz5cGZVjCwuhiie+LfBde4/Mc9QR8G+L3wtmT5cyoBxAg== + dependencies: + ajv "^6.10.0" + debug "^4.3.1" + +"@truffle/debug-utils@^6.0.22": + version "6.0.57" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.57.tgz#4e9a1051221c5f467daa398b0ca638d8b6408a82" + integrity sha512-Q6oI7zLaeNLB69ixjwZk2UZEWBY6b2OD1sjLMGDKBGR7GaHYiw96GLR2PFgPH1uwEeLmV4N78LYaQCrDsHbNeA== + dependencies: + "@truffle/codec" "^0.17.3" + "@trufflesuite/chromafi" "^3.0.0" + bn.js "^5.1.3" + chalk "^2.4.2" + debug "^4.3.1" + highlightjs-solidity "^2.0.6" + +"@truffle/error@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.1.1.tgz#e52026ac8ca7180d83443dca73c03e07ace2a301" + integrity sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA== + +"@truffle/error@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.2.2.tgz#1b4c4237c14dda792f20bd4f19ff4e4585b47796" + integrity sha512-TqbzJ0O8DHh34cu8gDujnYl4dUl6o2DE4PR6iokbybvnIm/L2xl6+Gv1VC+YJS45xfH83Yo3/Zyg/9Oq8/xZWg== + +"@truffle/interface-adapter@^0.5.16": + version "0.5.37" + resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.37.tgz#95d249c1912d2baaa63c54e8a138d3f476a1181a" + integrity sha512-lPH9MDgU+7sNDlJSClwyOwPCfuOimqsCx0HfGkznL3mcFRymc1pukAR1k17zn7ErHqBwJjiKAZ6Ri72KkS+IWw== + dependencies: + bn.js "^5.1.3" + ethers "^4.0.32" + web3 "1.10.0" + +"@trufflesuite/chromafi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz#f6956408c1af6a38a6ed1657783ce59504a1eb8b" + integrity sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ== + dependencies: + camelcase "^4.1.0" + chalk "^2.3.2" + cheerio "^1.0.0-rc.2" + detect-indent "^5.0.0" + highlight.js "^10.4.1" + lodash.merge "^4.6.2" + strip-ansi "^4.0.0" + strip-indent "^2.0.0" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -1144,13 +1411,23 @@ dependencies: "@types/node" "*" -"@types/bn.js@^5.1.0": +"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1": version "5.1.5" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== dependencies: "@types/node" "*" +"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + "@types/chai-as-promised@^7.1.3": version "7.1.8" resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" @@ -1163,6 +1440,11 @@ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== +"@types/chai@^4.2.0": + version "4.3.12" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.12.tgz#b192fe1c553b54f45d20543adc2ab88455a07d5e" + integrity sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw== + "@types/concat-stream@^1.6.0": version "1.6.1" resolved "https://registry.yarnpkg.com/@types/concat-stream/-/concat-stream-1.6.1.tgz#24bcfc101ecf68e886aaedce60dfd74b632a1b74" @@ -1185,6 +1467,18 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-cache-semantics@*": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + "@types/long@^4.0.1": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" @@ -1222,6 +1516,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== +"@types/node@^12.12.6": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + "@types/node@^18.11.9": version "18.19.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.3.tgz#e4723c4cb385641d61b983f6fe0b716abd5f8fc0" @@ -1259,6 +1558,13 @@ "@types/node" "*" safe-buffer "~5.1.1" +"@types/responselike@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" + integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== + dependencies: + "@types/node" "*" + "@types/secp256k1@^4.0.1": version "4.0.6" resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.6.tgz#d60ba2349a51c2cbc5e816dcd831a42029d376bf" @@ -1343,6 +1649,11 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +abortcontroller-polyfill@^1.7.3, abortcontroller-polyfill@^1.7.5: + version "1.7.5" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" + integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== + abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" @@ -1356,6 +1667,14 @@ abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: module-error "^1.0.1" queue-microtask "^1.2.3" +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + acorn-walk@^8.1.1: version "8.3.1" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.1.tgz#2f10f5b69329d90ae18c58bf1fa8fccd8b959a43" @@ -1396,6 +1715,16 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +ajv@^6.10.0, ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + 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" + ajv@^8.0.1: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" @@ -1439,6 +1768,11 @@ ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + ansi-regex@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" @@ -1529,6 +1863,11 @@ array-buffer-byte-length@^1.0.0: call-bind "^1.0.2" is-array-buffer "^3.0.1" +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1568,6 +1907,18 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -1578,6 +1929,11 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + async-retry@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" @@ -1605,6 +1961,16 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + axios@^0.21.1, axios@^0.21.2: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -1626,7 +1992,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-x@^3.0.2: +base-x@^3.0.2, base-x@^3.0.8: version "3.0.9" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== @@ -1638,16 +2004,43 @@ base64-js@^1.0.2, base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -bech32@1.1.4: +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +bech32@1.1.4, bech32@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +big-integer@1.6.36: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== + +big.js@^6.0.3: + version "6.2.1" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" + integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== + bigint-crypto-utils@^3.0.23: version "3.3.0" resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== + +bignumber.js@^9.0.0, bignumber.js@^9.0.1: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -1674,21 +2067,49 @@ blob-to-it@^1.0.1: dependencies: browser-readablestream-to-it "^1.0.3" +bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== -bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: +bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: +bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== +body-parser@1.20.2, body-parser@^1.16.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1748,7 +2169,7 @@ browserify-aes@^1.2.0: inherits "^2.0.1" safe-buffer "^5.0.1" -bs58@^4.0.0: +bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== @@ -1769,6 +2190,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1783,7 +2209,7 @@ buffer@4.9.2: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^6.0.1, buffer@^6.0.3: +buffer@6.0.3, buffer@^6.0.1, buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -1791,11 +2217,49 @@ buffer@^6.0.1, buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +buffer@^5.0.5, buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bufferutil@^4.0.1: + version "4.0.8" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea" + integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw== + dependencies: + node-gyp-build "^4.3.0" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-lookup@^6.0.4: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385" + integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww== + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" @@ -1805,6 +2269,24 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: get-intrinsic "^1.2.1" set-function-length "^1.1.1" +camel-case@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== + camelcase@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" @@ -1825,6 +2307,14 @@ catering@^2.1.0, catering@^2.1.1: resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== +cbor@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" + integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== + dependencies: + bignumber.js "^9.0.1" + nofilter "^1.0.4" + cbor@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" @@ -1851,6 +2341,19 @@ chai-as-promised@^7.1.1: dependencies: check-error "^1.0.2" +chai@^4.2.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" + integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== + 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" + chai@^4.3.7: version "4.3.10" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" @@ -1864,7 +2367,7 @@ chai@^4.3.7: pathval "^1.1.1" type-detect "^4.0.8" -chalk@^2.4.2: +chalk@^2.3.2, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1881,6 +2384,30 @@ chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +change-case@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.2.tgz#fd48746cce02f03f0a672577d1d3a8dc2eceb037" + integrity sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA== + dependencies: + camel-case "^3.0.0" + constant-case "^2.0.0" + dot-case "^2.1.0" + header-case "^1.0.0" + is-lower-case "^1.1.0" + is-upper-case "^1.1.0" + lower-case "^1.1.1" + lower-case-first "^1.0.0" + no-case "^2.3.2" + param-case "^2.1.0" + pascal-case "^2.0.0" + path-case "^2.1.0" + sentence-case "^2.1.0" + snake-case "^2.1.0" + swap-case "^1.1.0" + title-case "^2.1.0" + upper-case "^1.1.1" + upper-case-first "^1.1.0" + "charenc@>= 0.0.1": version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -1893,6 +2420,31 @@ check-error@^1.0.2, check-error@^1.0.3: dependencies: get-func-name "^2.0.2" +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.0.1" + htmlparser2 "^8.0.1" + parse5 "^7.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -1908,11 +2460,27 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +cids@^0.7.1: + version "0.7.5" + resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== + dependencies: + buffer "^5.5.0" + class-is "^1.1.0" + multibase "~0.6.0" + multicodec "^1.0.0" + multihashes "~0.4.15" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1921,6 +2489,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +class-is@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== + classic-level@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" @@ -1947,6 +2520,15 @@ cli-table3@^0.5.0: optionalDependencies: colors "^1.1.2" +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -1956,6 +2538,18 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -1985,7 +2579,7 @@ colors@1.4.0, colors@^1.1.2: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.6, combined-stream@^1.0.8: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2042,16 +2636,68 @@ concat-stream@^1.6.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +constant-case@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46" + integrity sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ== + dependencies: + snake-case "^2.1.0" + upper-case "^1.1.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-hash@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" + integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== + dependencies: + cids "^0.7.1" + multicodec "^0.5.5" + multihashes "^0.4.15" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + cookie@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cors@^2.8.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + crc-32@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" @@ -2092,13 +2738,20 @@ cross-env@^7.0.3: dependencies: cross-spawn "^7.0.1" -cross-fetch@^3.1.5: +cross-fetch@^3.1.4, cross-fetch@^3.1.5: version "3.1.8" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== dependencies: node-fetch "^2.6.12" +cross-fetch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + cross-spawn@^7.0.0, cross-spawn@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2113,6 +2766,50 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== +crypto-addr-codec@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.8.tgz#45c4b24e2ebce8e24a54536ee0ca25b65787b016" + integrity sha512-GqAK90iLLgP3FvhNmHbpT3wR6dEdaM8hZyZtLX29SPardh3OA13RFLHDR6sntGCgRWOfiHqW6sIyohpNqOtV/g== + dependencies: + base-x "^3.0.8" + big-integer "1.6.36" + blakejs "^1.1.0" + bs58 "^4.0.1" + ripemd160-min "0.0.6" + safe-buffer "^5.2.0" + sha3 "^2.1.1" + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + data-uri-to-buffer@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" @@ -2123,6 +2820,13 @@ death@^1.1.0: resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== +debug@2.6.9, debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -2130,11 +2834,35 @@ debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: dependencies: ms "2.1.2" +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decode-uri-component@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-eql@^4.0.1, deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" @@ -2152,6 +2880,11 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + define-data-property@^1.0.1, define-data-property@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" @@ -2180,6 +2913,16 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== + detect-port@^1.3.0: version "1.5.1" resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" @@ -2221,6 +2964,55 @@ dns-over-http-resolver@^1.2.3: native-fetch "^3.0.0" receptacle "^1.3.2" +dns-packet@^5.3.0: + version "5.6.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dot-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee" + integrity sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug== + dependencies: + no-case "^2.2.0" + dotenv@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" @@ -2231,6 +3023,19 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + electron-fetch@^1.7.2: version "1.9.1" resolved "https://registry.yarnpkg.com/electron-fetch/-/electron-fetch-1.9.1.tgz#e28bfe78d467de3f2dec884b1d72b8b05322f30f" @@ -2238,7 +3043,7 @@ electron-fetch@^1.7.2: dependencies: encoding "^0.1.13" -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -2266,6 +3071,11 @@ encode-utf8@^1.0.2: resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -2273,6 +3083,13 @@ encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.0, enquirer@^2.3.6: version "2.4.1" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" @@ -2281,6 +3098,11 @@ enquirer@^2.3.0, enquirer@^2.3.6: ansi-colors "^4.1.1" strip-ansi "^6.0.1" +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -2291,6 +3113,13 @@ err-code@^3.0.1: resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920" integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA== +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + es-abstract@^1.22.1: version "1.22.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" @@ -2361,11 +3190,48 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@^0.10.62, es5-ext@~0.10.14: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + esniff "^2.0.1" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + escape-string-regexp@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -2388,6 +3254,16 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + esprima@2.7.x, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" @@ -2408,6 +3284,19 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.0, eth-ens-namehash@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw== + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + eth-gas-reporter@^0.2.25: version "0.2.27" resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz#928de8548a674ed64c7ba0bf5795e63079150d4e" @@ -2427,6 +3316,27 @@ eth-gas-reporter@^0.2.25: sha1 "^1.1.1" sync-request "^6.0.0" +eth-lib@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.1.26: + version "0.1.29" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + ethereum-bloom-filters@^1.0.6: version "1.0.10" resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" @@ -2475,6 +3385,18 @@ ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: "@scure/bip32" "1.3.1" "@scure/bip39" "1.2.1" +ethereum-ens@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/ethereum-ens/-/ethereum-ens-0.8.0.tgz#6d0f79acaa61fdbc87d2821779c4e550243d4c57" + integrity sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg== + dependencies: + bluebird "^3.4.7" + eth-ens-namehash "^2.0.0" + js-sha3 "^0.5.7" + pako "^1.0.4" + underscore "^1.8.3" + web3 "^1.0.0-beta.34" + ethereumjs-abi@^0.6.8: version "0.6.8" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" @@ -2496,7 +3418,7 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: ethjs-util "0.1.6" rlp "^2.2.3" -ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.4: +ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: version "7.1.5" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== @@ -2507,7 +3429,22 @@ ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.4: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.6.2, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: +ethers@^4.0.0-beta.1, ethers@^4.0.32: + version "4.0.49" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" + integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== + 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" + +ethers@^5.0.13, ethers@^5.6.2, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -2559,11 +3496,24 @@ ethjs-util@0.1.6, ethjs-util@^0.1.6: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -2572,16 +3522,82 @@ evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +express@^4.14.0: + version "4.18.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.3.tgz#6870746f3ff904dee1819b82e4b51509afffb0d4" + integrity sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + extract-files@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a" integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ== +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fast-base64-decode@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418" integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q== +fast-check@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.1.tgz#72c5ae7022a4e86504762e773adfb8a5b0b01252" + integrity sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA== + dependencies: + pure-rand "^5.0.1" + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -2603,6 +3619,11 @@ fast-glob@^3.0.3: merge2 "^1.3.0" micromatch "^4.0.4" +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -2622,6 +3643,19 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + find-replace@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" @@ -2637,6 +3671,14 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -2676,6 +3718,16 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data-encoder@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96" + integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== + form-data@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -2703,6 +3755,20 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + fp-ts@1.19.3: version "1.19.3" resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" @@ -2713,6 +3779,11 @@ fp-ts@^1.0.0: resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -2733,6 +3804,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^7.0.0, fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -2761,6 +3841,13 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -2801,6 +3888,11 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -2831,6 +3923,18 @@ get-port@^3.1.0: resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -2839,6 +3943,13 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + ghost-testrpc@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" @@ -2928,6 +4039,14 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" +global@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + globalthis@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" @@ -2956,6 +4075,42 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +got@12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4" + integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig== + dependencies: + "@sindresorhus/is" "^4.6.0" + "@szmarczak/http-timer" "^5.0.1" + "@types/cacheable-request" "^6.0.2" + "@types/responselike" "^1.0.0" + cacheable-lookup "^6.0.4" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + form-data-encoder "1.7.1" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^2.0.0" + +got@^11.8.5: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -2987,6 +4142,19 @@ handlebars@^4.0.1: optionalDependencies: uglify-js "^3.1.4" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + hardhat-deploy@^0.11.26: version "0.11.44" resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.44.tgz#a7a771a675a3837ce4c321f2c18d4b6fa1ed03a0" @@ -3133,6 +4301,19 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" +hash-test-vectors@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/hash-test-vectors/-/hash-test-vectors-1.3.2.tgz#f050fde1aff46ec28dcf4f70e4e3238cd5000f4c" + integrity sha512-PKd/fitmsrlWGh3OpKbgNLE04ZQZsvs1ZkuLoQpeIKuwx+6CYVNdW6LaPIS1QAdZvV40+skk0w4YomKnViUnvQ== + +hash.js@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" + hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -3153,11 +4334,29 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +header-case@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d" + integrity sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.3" + "heap@>= 0.2.0": version "0.2.7" resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== +highlight.js@^10.4.1: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + +highlightjs-solidity@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-2.0.6.tgz#e7a702a2b05e0a97f185e6ba39fd4846ad23a990" + integrity sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3167,6 +4366,21 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + http-basic@^8.1.1: version "8.1.3" resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" @@ -3177,6 +4391,11 @@ http-basic@^8.1.1: http-response-object "^3.0.1" parse-cache-control "^1.0.1" +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -3188,6 +4407,11 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg== + http-response-object@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" @@ -3195,6 +4419,31 @@ http-response-object@^3.0.1: dependencies: "@types/node" "^10.0.3" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +http2-wrapper@^2.1.10: + version "2.2.1" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" + integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -3217,7 +4466,14 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.4, ieee754@^1.2.1: +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -3294,6 +4550,11 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + io-ts@1.10.4: version "1.10.4" resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" @@ -3306,6 +4567,11 @@ ip-regex@^4.0.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + ipfs-core-types@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/ipfs-core-types/-/ipfs-core-types-0.6.1.tgz#d28318e38578d1f95ef1d97e0e456c235bf2c283" @@ -3413,6 +4679,11 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: get-intrinsic "^1.2.0" is-typed-array "^1.1.10" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -3469,6 +4740,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -3479,6 +4757,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" @@ -3505,6 +4788,13 @@ is-ip@^3.1.0: dependencies: ip-regex "^4.0.0" +is-lower-case@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393" + integrity sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA== + dependencies: + lower-case "^1.1.0" + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -3563,11 +4853,28 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed- dependencies: which-typed-array "^1.1.11" +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-upper-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" + integrity sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw== + dependencies: + upper-case "^1.1.0" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -3608,6 +4915,11 @@ isomorphic-unfetch@^3.0.0, isomorphic-unfetch@^3.1.0: node-fetch "^2.6.1" unfetch "^4.2.0" +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + it-all@^1.0.2, it-all@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/it-all/-/it-all-1.0.6.tgz#852557355367606295c4c3b7eff0136f07749335" @@ -3713,6 +5025,11 @@ js-sdsl@^4.1.4: resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== +js-sha3@0.5.7, js-sha3@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== + js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -3733,11 +5050,36 @@ js-yaml@4.1.0: dependencies: argparse "^2.0.1" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + json-schema-traverse@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -3766,6 +5108,16 @@ jsonschema@^1.2.4: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + keccak@^3.0.0, keccak@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" @@ -3775,6 +5127,13 @@ keccak@^3.0.0, keccak@^3.0.2: node-gyp-build "^4.2.0" readable-stream "^3.6.0" +keyv@^4.0.0: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -3787,6 +5146,13 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + level-supports@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" @@ -3816,6 +5182,17 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3831,11 +5208,21 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.assign@^4.0.3, lodash.assign@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== + lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" @@ -3866,6 +5253,28 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" +lower-case-first@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1" + integrity sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA== + dependencies: + lower-case "^1.1.2" + +lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -3919,6 +5328,11 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + memory-level@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" @@ -3933,6 +5347,11 @@ memorystream@^0.3.1: resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + merge-options@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7" @@ -3945,6 +5364,11 @@ merge2@^1.2.3, merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + micro-ftch@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" @@ -3963,13 +5387,35 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12: +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== + dependencies: + dom-walk "^0.1.0" + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -4006,12 +5452,39 @@ minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.7: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": version "7.0.4" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -mkdirp@0.5.x: +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w== + dependencies: + mkdirp "*" + +mkdirp@*: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + +mkdirp@0.5.x, mkdirp@^0.5.5: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -4057,6 +5530,11 @@ mocha@10.2.0, mocha@^10.0.0, mocha@^10.1.0, mocha@^10.2.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" +mock-fs@^4.1.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" + integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== + module-error@^1.0.1, module-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" @@ -4067,6 +5545,11 @@ mrmime@^1.0.0: resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -4096,11 +5579,51 @@ multiaddr@^10.0.0: uint8arrays "^3.0.0" varint "^6.0.0" +multibase@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multicodec@^0.5.5: + version "0.5.7" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" + integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== + dependencies: + varint "^5.0.0" + +multicodec@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== + dependencies: + buffer "^5.6.0" + varint "^5.0.0" + multiformats@^9.4.1, multiformats@^9.4.2, multiformats@^9.4.5, multiformats@^9.5.4: version "9.9.0" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== +multihashes@^0.4.15, multihashes@~0.4.15: + version "0.4.21" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== + dependencies: + buffer "^5.5.0" + multibase "^0.7.0" + varint "^5.0.0" + murmur-128@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" @@ -4110,6 +5633,16 @@ murmur-128@^0.2.1: fmix "^0.1.0" imul "^1.0.0" +nano-base32@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" + integrity sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw== + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== + nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -4135,11 +5668,28 @@ native-fetch@^3.0.0: resolved "https://registry.yarnpkg.com/native-fetch/-/native-fetch-3.0.0.tgz#06ccdd70e79e171c365c75117959cf4fe14a09bb" integrity sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +no-case@^2.2.0, no-case@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + node-addon-api@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" @@ -4168,6 +5718,11 @@ node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== +nofilter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" + integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== + nofilter@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" @@ -4180,11 +5735,38 @@ nopt@3.x: dependencies: abbrev "1" +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" @@ -4193,7 +5775,12 @@ number-to-bn@1.7.0: bn.js "4.11.6" strip-hex-prefix "1.0.0" -object-assign@^4.1.0: +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -4223,7 +5810,21 @@ obliterator@^2.0.0: resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== -once@1.x, once@^1.3.0: +oboe@2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" + integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA== + dependencies: + http-https "^1.0.0" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -4247,11 +5848,28 @@ ordinal@^1.0.3: resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== -os-tmpdir@~1.0.2: - version "1.0.2" +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + p-defer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83" @@ -4305,6 +5923,18 @@ p-try@^1.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== +pako@^1.0.4: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +param-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w== + dependencies: + no-case "^2.2.0" + parse-cache-control@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" @@ -4315,6 +5945,60 @@ parse-duration@^1.0.0: resolved "https://registry.yarnpkg.com/parse-duration/-/parse-duration-1.1.0.tgz#5192084c5d8f2a3fd676d04a451dbd2e05a1819c" integrity sha512-z6t9dvSJYaPoQq7quMzdEagSFtpGu+utzHqqxmpVWNNZRIXnvqyCvn9XsTdh7c/w0Bqmdz3RB3YnRaKtpRtEXQ== +parse-headers@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" + integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e" + integrity sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ== + dependencies: + camel-case "^3.0.0" + upper-case-first "^1.1.0" + +path-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5" + integrity sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q== + dependencies: + no-case "^2.2.0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -4348,6 +6032,20 @@ path-scurry@^1.10.1: lru-cache "^9.1.1 || ^10.0.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4369,16 +6067,38 @@ pbkdf2@^3.0.17: safe-buffer "^5.0.1" sha.js "^2.4.8" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -4394,6 +6114,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise@^8.0.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" @@ -4434,16 +6159,54 @@ protobufjs@^6.10.2: "@types/node" ">=13.7.0" long "^4.0.0" +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -punycode@^2.1.0: +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== + +punycode@^2.1.0, punycode@^2.1.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== +pure-rand@^5.0.1: + version "5.0.5" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-5.0.5.tgz#bda2a7f6a1fc0f284d78d78ca5902f26f2ad35cf" + integrity sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + qs@^6.4.0, qs@^6.9.4: version "6.11.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" @@ -4451,11 +6214,30 @@ qs@^6.4.0, qs@^6.9.4: dependencies: side-channel "^1.0.4" +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -4463,7 +6245,12 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -raw-body@^2.4.1: +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2, raw-body@^2.4.1: version "2.5.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== @@ -4480,6 +6267,23 @@ react-native-fetch-api@^2.0.0: dependencies: p-defer "^3.0.0" +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + readable-stream@^2.2.2: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" @@ -4535,6 +6339,11 @@ reduce-flatten@^2.0.0: resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regexp.prototype.flags@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" @@ -4558,16 +6367,57 @@ req-from@^2.0.0: dependencies: resolve-from "^3.0.0" +request@^2.79.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + 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" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q== + require-from-string@^2.0.0, require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + +resolve-alpn@^1.0.0, resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -4585,7 +6435,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6: +resolve@^1.1.6, resolve@^1.10.0: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -4594,6 +6444,13 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + retimer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/retimer/-/retimer-2.0.0.tgz#e8bd68c5e5a8ec2f49ccb5c636db84c04063bbca" @@ -4635,7 +6492,12 @@ rimraf@^5.0.5: dependencies: glob "^10.3.7" -ripemd160@^2.0.0, ripemd160@^2.0.1: +ripemd160-min@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" + integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== + +ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== @@ -4679,7 +6541,7 @@ safe-array-concat@^1.0.1: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -4698,7 +6560,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -4723,7 +6585,12 @@ sc-istanbul@^0.4.5: which "^1.1.1" wordwrap "^1.0.0" -scrypt-js@3.0.1, scrypt-js@^3.0.0: +scrypt-js@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" + integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== + +scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== @@ -4737,7 +6604,7 @@ secp256k1@^4.0.1: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" -semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== @@ -4754,6 +6621,40 @@ semver@^7.3.4: dependencies: lru-cache "^6.0.0" +semver@^7.5.4: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +sentence-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4" + integrity sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ== + dependencies: + no-case "^2.2.0" + upper-case-first "^1.1.2" + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -4761,6 +6662,32 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + set-function-length@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" @@ -4780,6 +6707,11 @@ set-function-name@^2.0.0: functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" +setimmediate@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" + integrity sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog== + setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -4806,6 +6738,13 @@ sha1@^1.1.1: charenc ">= 0.0.1" crypt ">= 0.0.1" +sha3@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" + integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== + dependencies: + buffer "6.0.3" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -4846,6 +6785,20 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^2.7.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" + integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -4860,6 +6813,13 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +snake-case@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" + integrity sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q== + dependencies: + no-case "^2.2.0" + solc@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" @@ -4875,6 +6835,17 @@ solc@0.7.3: semver "^5.5.0" tmp "0.0.33" +solc@^0.4.20: + version "0.4.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" + integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== + dependencies: + fs-extra "^0.30.0" + memorystream "^0.3.1" + require-from-string "^1.1.0" + semver "^5.3.0" + yargs "^4.7.1" + solidity-ast@^0.4.51: version "0.4.55" resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.55.tgz#00b685e6eefb2e8dfb67df1fe0afbe3b3bfb4b28" @@ -4908,7 +6879,7 @@ solidity-coverage@^0.8.2: shelljs "^0.8.3" web3-utils "^1.3.6" -source-map-support@^0.5.13: +source-map-support@^0.5.13, source-map-support@^0.5.19: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -4928,11 +6899,52 @@ source-map@~0.2.0: dependencies: amdefine ">=0.0.4" +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.17" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz#887da8aa73218e51a1d917502d79863161a93f9c" + integrity sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sshpk@^1.7.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== + 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" + stacktrace-parser@^0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" @@ -4952,6 +6964,11 @@ stream-to-it@^0.2.2: dependencies: get-iterator "^1.0.2" +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + string-format@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" @@ -4966,6 +6983,15 @@ string-format@^2.0.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -5031,6 +7057,13 @@ string_decoder@~1.1.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -5045,6 +7078,13 @@ strip-ansi@^7.0.1: dependencies: ansi-regex "^6.0.1" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" @@ -5052,6 +7092,11 @@ strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed "1.0.0" +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA== + strip-json-comments@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -5090,6 +7135,31 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swap-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3" + integrity sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ== + dependencies: + lower-case "^1.1.1" + upper-case "^1.1.1" + +swarm-js@^0.1.40: + version "0.1.42" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979" + integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^11.8.5" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request "^1.0.1" + sync-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" @@ -5127,6 +7197,24 @@ table@^6.8.0: string-width "^4.2.3" strip-ansi "^6.0.1" +tar@^4.0.2: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + +testrpc@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" + integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== + then-request@^6.0.0: version "6.0.2" resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" @@ -5144,6 +7232,11 @@ then-request@^6.0.0: promise "^8.0.0" qs "^6.4.0" +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + timeout-abort-controller@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/timeout-abort-controller/-/timeout-abort-controller-1.1.1.tgz#2c3c3c66f13c783237987673c276cbd7a9762f29" @@ -5157,6 +7250,14 @@ tiny-case@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== +title-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" + integrity sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q== + dependencies: + no-case "^2.2.0" + upper-case "^1.0.3" + tmp-promise@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" @@ -5195,6 +7296,14 @@ toposort@^2.0.2: resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -5249,11 +7358,23 @@ tsort@0.0.1: resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + tweetnacl-util@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" @@ -5286,6 +7407,24 @@ type-fest@^2.19.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + typechain@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" @@ -5341,6 +7480,13 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -5380,6 +7526,11 @@ uint8arrays@^3.0.0: dependencies: multiformats "^9.4.2" +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -5390,6 +7541,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +underscore@^1.8.3: + version "1.13.6" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" + integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== + undici-types@~5.26.4: version "5.26.5" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" @@ -5417,11 +7573,23 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== +upper-case-first@^1.1.0, upper-case-first@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" + integrity sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ== + dependencies: + upper-case "^1.1.1" + +upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -5429,7 +7597,19 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -utf8@3.0.0: +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== + +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +utf8@3.0.0, utf8@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== @@ -5439,7 +7619,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util@^0.12.3: +util@^0.12.3, util@^0.12.5: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -5450,21 +7630,68 @@ util@^0.12.3: is-typed-array "^1.1.3" which-typed-array "^1.1.2" +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" + integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +varint@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + varint@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + web-encoding@1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864" @@ -5479,6 +7706,439 @@ web-streams-polyfill@^3.1.1: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz#32e26522e05128203a7de59519be3c648004343b" integrity sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ== +web3-bzz@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.10.0.tgz#ac74bc71cdf294c7080a79091079192f05c5baed" + integrity sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA== + dependencies: + "@types/node" "^12.12.6" + got "12.1.0" + swarm-js "^0.1.40" + +web3-bzz@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.10.4.tgz#dcc787970767d9004c73d11d0eeef774ce16b880" + integrity sha512-ZZ/X4sJ0Uh2teU9lAGNS8EjveEppoHNQiKlOXAjedsrdWuaMErBPdLQjXfcrYvN6WM6Su9PMsAxf3FXXZ+HwQw== + dependencies: + "@types/node" "^12.12.6" + got "12.1.0" + swarm-js "^0.1.40" + +web3-core-helpers@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.0.tgz#1016534c51a5df77ed4f94d1fcce31de4af37fad" + integrity sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g== + dependencies: + web3-eth-iban "1.10.0" + web3-utils "1.10.0" + +web3-core-helpers@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz#bd2b4140df2016d5dd3bb2b925fc29ad8678677c" + integrity sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g== + dependencies: + web3-eth-iban "1.10.4" + web3-utils "1.10.4" + +web3-core-method@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.0.tgz#82668197fa086e8cc8066742e35a9d72535e3412" + integrity sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-core-subscriptions "1.10.0" + web3-utils "1.10.0" + +web3-core-method@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.4.tgz#566b52f006d3cbb13b21b72b8d2108999bf5d6bf" + integrity sha512-uZTb7flr+Xl6LaDsyTeE2L1TylokCJwTDrIVfIfnrGmnwLc6bmTWCCrm71sSrQ0hqs6vp/MKbQYIYqUN0J8WyA== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.10.4" + web3-core-promievent "1.10.4" + web3-core-subscriptions "1.10.4" + web3-utils "1.10.4" + +web3-core-promievent@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.0.tgz#cbb5b3a76b888df45ed3a8d4d8d4f54ccb66a37b" + integrity sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg== + dependencies: + eventemitter3 "4.0.4" + +web3-core-promievent@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz#629b970b7934430b03c5033c79f3bb3893027e22" + integrity sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ== + dependencies: + eventemitter3 "4.0.4" + +web3-core-requestmanager@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.0.tgz#4b34f6e05837e67c70ff6f6993652afc0d54c340" + integrity sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ== + dependencies: + util "^0.12.5" + web3-core-helpers "1.10.0" + web3-providers-http "1.10.0" + web3-providers-ipc "1.10.0" + web3-providers-ws "1.10.0" + +web3-core-requestmanager@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.4.tgz#eb1f147e6b9df84e3a37e602162f8925bdb4bb9a" + integrity sha512-vqP6pKH8RrhT/2MoaU+DY/OsYK9h7HmEBNCdoMj+4ZwujQtw/Mq2JifjwsJ7gits7Q+HWJwx8q6WmQoVZAWugg== + dependencies: + util "^0.12.5" + web3-core-helpers "1.10.4" + web3-providers-http "1.10.4" + web3-providers-ipc "1.10.4" + web3-providers-ws "1.10.4" + +web3-core-subscriptions@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.0.tgz#b534592ee1611788fc0cb0b95963b9b9b6eacb7c" + integrity sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + +web3-core-subscriptions@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.4.tgz#2f4dcb404237e92802a563265d11a33934dc38e6" + integrity sha512-o0lSQo/N/f7/L76C0HV63+S54loXiE9fUPfHFcTtpJRQNDBVsSDdWRdePbWwR206XlsBqD5VHApck1//jEafTw== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.4" + +web3-core@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.0.tgz#9aa07c5deb478cf356c5d3b5b35afafa5fa8e633" + integrity sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ== + dependencies: + "@types/bn.js" "^5.1.1" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-requestmanager "1.10.0" + web3-utils "1.10.0" + +web3-core@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.4.tgz#639de68b8b9871d2dc8892e0dd4e380cb1361a98" + integrity sha512-B6elffYm81MYZDTrat7aEhnhdtVE3lDBUZft16Z8awYMZYJDbnykEbJVS+l3mnA7AQTnSDr/1MjWofGDLBJPww== + dependencies: + "@types/bn.js" "^5.1.1" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.10.4" + web3-core-method "1.10.4" + web3-core-requestmanager "1.10.4" + web3-utils "1.10.4" + +web3-eth-abi@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.0.tgz#53a7a2c95a571e205e27fd9e664df4919483cce1" + integrity sha512-cwS+qRBWpJ43aI9L3JS88QYPfFcSJJ3XapxOQ4j40v6mk7ATpA8CVK1vGTzpihNlOfMVRBkR95oAj7oL6aiDOg== + dependencies: + "@ethersproject/abi" "^5.6.3" + web3-utils "1.10.0" + +web3-eth-abi@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz#16c19d0bde0aaf8c1a56cb7743a83156d148d798" + integrity sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ== + dependencies: + "@ethersproject/abi" "^5.6.3" + web3-utils "1.10.4" + +web3-eth-accounts@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.0.tgz#2942beca0a4291455f32cf09de10457a19a48117" + integrity sha512-wiq39Uc3mOI8rw24wE2n15hboLE0E9BsQLdlmsL4Zua9diDS6B5abXG0XhFcoNsXIGMWXVZz4TOq3u4EdpXF/Q== + dependencies: + "@ethereumjs/common" "2.5.0" + "@ethereumjs/tx" "3.3.2" + eth-lib "0.2.8" + ethereumjs-util "^7.1.5" + scrypt-js "^3.0.1" + uuid "^9.0.0" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-utils "1.10.0" + +web3-eth-accounts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.4.tgz#df30e85a7cd70e475f8cf52361befba408829e34" + integrity sha512-ysy5sVTg9snYS7tJjxVoQAH6DTOTkRGR8emEVCWNGLGiB9txj+qDvSeT0izjurS/g7D5xlMAgrEHLK1Vi6I3yg== + dependencies: + "@ethereumjs/common" "2.6.5" + "@ethereumjs/tx" "3.5.2" + "@ethereumjs/util" "^8.1.0" + eth-lib "0.2.8" + scrypt-js "^3.0.1" + uuid "^9.0.0" + web3-core "1.10.4" + web3-core-helpers "1.10.4" + web3-core-method "1.10.4" + web3-utils "1.10.4" + +web3-eth-contract@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.0.tgz#8e68c7654576773ec3c91903f08e49d0242c503a" + integrity sha512-MIC5FOzP/+2evDksQQ/dpcXhSqa/2hFNytdl/x61IeWxhh6vlFeSjq0YVTAyIzdjwnL7nEmZpjfI6y6/Ufhy7w== + dependencies: + "@types/bn.js" "^5.1.1" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-promievent "1.10.0" + web3-core-subscriptions "1.10.0" + web3-eth-abi "1.10.0" + web3-utils "1.10.0" + +web3-eth-contract@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.4.tgz#22d39f04e11d9ff4e726e8025a56d78e843a2c3d" + integrity sha512-Q8PfolOJ4eV9TvnTj1TGdZ4RarpSLmHnUnzVxZ/6/NiTfe4maJz99R0ISgwZkntLhLRtw0C7LRJuklzGYCNN3A== + dependencies: + "@types/bn.js" "^5.1.1" + web3-core "1.10.4" + web3-core-helpers "1.10.4" + web3-core-method "1.10.4" + web3-core-promievent "1.10.4" + web3-core-subscriptions "1.10.4" + web3-eth-abi "1.10.4" + web3-utils "1.10.4" + +web3-eth-ens@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.0.tgz#96a676524e0b580c87913f557a13ed810cf91cd9" + integrity sha512-3hpGgzX3qjgxNAmqdrC2YUQMTfnZbs4GeLEmy8aCWziVwogbuqQZ+Gzdfrym45eOZodk+lmXyLuAdqkNlvkc1g== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-eth-abi "1.10.0" + web3-eth-contract "1.10.0" + web3-utils "1.10.0" + +web3-eth-ens@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.4.tgz#3d991adac52bc8e598f1f1b8528337fa6291004c" + integrity sha512-LLrvxuFeVooRVZ9e5T6OWKVflHPFgrVjJ/jtisRWcmI7KN/b64+D/wJzXqgmp6CNsMQcE7rpmf4CQmJCrTdsgg== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.10.4" + web3-core-helpers "1.10.4" + web3-core-promievent "1.10.4" + web3-eth-abi "1.10.4" + web3-eth-contract "1.10.4" + web3-utils "1.10.4" + +web3-eth-iban@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz#5a46646401965b0f09a4f58e7248c8a8cd22538a" + integrity sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg== + dependencies: + bn.js "^5.2.1" + web3-utils "1.10.0" + +web3-eth-iban@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz#bc61b4a1930d19b1df8762c606d669902558e54d" + integrity sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw== + dependencies: + bn.js "^5.2.1" + web3-utils "1.10.4" + +web3-eth-personal@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.0.tgz#94d525f7a29050a0c2a12032df150ac5ea633071" + integrity sha512-anseKn98w/d703eWq52uNuZi7GhQeVjTC5/svrBWEKob0WZ5kPdo+EZoFN0sp5a5ubbrk/E0xSl1/M5yORMtpg== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-net "1.10.0" + web3-utils "1.10.0" + +web3-eth-personal@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.4.tgz#e2ee920f47e84848288e03442659cdbb2c4deea2" + integrity sha512-BRa/hs6jU1hKHz+AC/YkM71RP3f0Yci1dPk4paOic53R4ZZG4MgwKRkJhgt3/GPuPliwS46f/i5A7fEGBT4F9w== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.10.4" + web3-core-helpers "1.10.4" + web3-core-method "1.10.4" + web3-net "1.10.4" + web3-utils "1.10.4" + +web3-eth@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.0.tgz#38b905e2759697c9624ab080cfcf4e6c60b3a6cf" + integrity sha512-Z5vT6slNMLPKuwRyKGbqeGYC87OAy8bOblaqRTgg94CXcn/mmqU7iPIlG4506YdcdK3x6cfEDG7B6w+jRxypKA== + dependencies: + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-subscriptions "1.10.0" + web3-eth-abi "1.10.0" + web3-eth-accounts "1.10.0" + web3-eth-contract "1.10.0" + web3-eth-ens "1.10.0" + web3-eth-iban "1.10.0" + web3-eth-personal "1.10.0" + web3-net "1.10.0" + web3-utils "1.10.0" + +web3-eth@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.4.tgz#3a908c635cb5d935bd30473e452f3bd7f2ee66a5" + integrity sha512-Sql2kYKmgt+T/cgvg7b9ce24uLS7xbFrxE4kuuor1zSCGrjhTJ5rRNG8gTJUkAJGKJc7KgnWmgW+cOfMBPUDSA== + dependencies: + web3-core "1.10.4" + web3-core-helpers "1.10.4" + web3-core-method "1.10.4" + web3-core-subscriptions "1.10.4" + web3-eth-abi "1.10.4" + web3-eth-accounts "1.10.4" + web3-eth-contract "1.10.4" + web3-eth-ens "1.10.4" + web3-eth-iban "1.10.4" + web3-eth-personal "1.10.4" + web3-net "1.10.4" + web3-utils "1.10.4" + +web3-net@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.0.tgz#be53e7f5dafd55e7c9013d49c505448b92c9c97b" + integrity sha512-NLH/N3IshYWASpxk4/18Ge6n60GEvWBVeM8inx2dmZJVmRI6SJIlUxbL8jySgiTn3MMZlhbdvrGo8fpUW7a1GA== + dependencies: + web3-core "1.10.0" + web3-core-method "1.10.0" + web3-utils "1.10.0" + +web3-net@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.4.tgz#20e12c60e4477d4298979d8d5d66b9abf8e66a09" + integrity sha512-mKINnhOOnZ4koA+yV2OT5s5ztVjIx7IY9a03w6s+yao/BUn+Luuty0/keNemZxTr1E8Ehvtn28vbOtW7Ids+Ow== + dependencies: + web3-core "1.10.4" + web3-core-method "1.10.4" + web3-utils "1.10.4" + +web3-providers-http@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.0.tgz#864fa48675e7918c9a4374e5f664b32c09d0151b" + integrity sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA== + dependencies: + abortcontroller-polyfill "^1.7.3" + cross-fetch "^3.1.4" + es6-promise "^4.2.8" + web3-core-helpers "1.10.0" + +web3-providers-http@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.4.tgz#ca7aa58aeaf8123500c24ffe0595896319f830e8" + integrity sha512-m2P5Idc8hdiO0l60O6DSCPw0kw64Zgi0pMjbEFRmxKIck2Py57RQMu4bxvkxJwkF06SlGaEQF8rFZBmuX7aagQ== + dependencies: + abortcontroller-polyfill "^1.7.5" + cross-fetch "^4.0.0" + es6-promise "^4.2.8" + web3-core-helpers "1.10.4" + +web3-providers-ipc@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz#9747c7a6aee96a51488e32fa7c636c3460b39889" + integrity sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.10.0" + +web3-providers-ipc@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.4.tgz#2e03437909e4e7771d646ff05518efae44b783c3" + integrity sha512-YRF/bpQk9z3WwjT+A6FI/GmWRCASgd+gC0si7f9zbBWLXjwzYAKG73bQBaFRAHex1hl4CVcM5WUMaQXf3Opeuw== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.10.4" + +web3-providers-ws@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz#cb0b87b94c4df965cdf486af3a8cd26daf3975e5" + integrity sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + websocket "^1.0.32" + +web3-providers-ws@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.4.tgz#55d0c3ba36c6a79d105f02e20a707eb3978e7f82" + integrity sha512-j3FBMifyuFFmUIPVQR4pj+t5ILhAexAui0opgcpu9R5LxQrLRUZxHSnU+YO25UycSOa/NAX8A+qkqZNpcFAlxA== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.4" + websocket "^1.0.32" + +web3-shh@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.0.tgz#c2979b87e0f67a7fef2ce9ee853bd7bfbe9b79a8" + integrity sha512-uNUUuNsO2AjX41GJARV9zJibs11eq6HtOe6Wr0FtRUcj8SN6nHeYIzwstAvJ4fXA53gRqFMTxdntHEt9aXVjpg== + dependencies: + web3-core "1.10.0" + web3-core-method "1.10.0" + web3-core-subscriptions "1.10.0" + web3-net "1.10.0" + +web3-shh@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.4.tgz#9852d6f3d05678e31e49235a60fea10ca7a9e21d" + integrity sha512-cOH6iFFM71lCNwSQrC3niqDXagMqrdfFW85hC9PFUrAr3PUrIem8TNstTc3xna2bwZeWG6OBy99xSIhBvyIACw== + dependencies: + web3-core "1.10.4" + web3-core-method "1.10.4" + web3-core-subscriptions "1.10.4" + web3-net "1.10.4" + +web3-utils@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578" + integrity sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg== + 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" + +web3-utils@1.10.4, web3-utils@^1.0.0-beta.31: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" + integrity sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A== + dependencies: + "@ethereumjs/util" "^8.1.0" + bn.js "^5.2.1" + 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" + web3-utils@^1.3.6: version "1.10.3" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" @@ -5493,11 +8153,49 @@ web3-utils@^1.3.6: randombytes "^2.1.0" utf8 "3.0.0" +web3@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.0.tgz#2fde0009f59aa756c93e07ea2a7f3ab971091274" + integrity sha512-YfKY9wSkGcM8seO+daR89oVTcbu18NsVfvOngzqMYGUU0pPSQmE57qQDvQzUeoIOHAnXEBNzrhjQJmm8ER0rng== + dependencies: + web3-bzz "1.10.0" + web3-core "1.10.0" + web3-eth "1.10.0" + web3-eth-personal "1.10.0" + web3-net "1.10.0" + web3-shh "1.10.0" + web3-utils "1.10.0" + +web3@^1.0.0-beta.34: + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.4.tgz#5d5e59b976eaf758b060fe1a296da5fe87bdc79c" + integrity sha512-kgJvQZjkmjOEKimx/tJQsqWfRDPTTcBfYPa9XletxuHLpHcXdx67w8EFn5AW3eVxCutE9dTVHgGa9VYe8vgsEA== + dependencies: + web3-bzz "1.10.4" + web3-core "1.10.4" + web3-eth "1.10.4" + web3-eth-personal "1.10.4" + web3-net "1.10.4" + web3-shh "1.10.4" + web3-utils "1.10.4" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== +websocket@^1.0.32: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -5517,6 +8215,11 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: version "1.1.13" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" @@ -5542,6 +8245,11 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== + word-wrap@~1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -5574,6 +8282,14 @@ workerpool@6.2.1: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" @@ -5593,17 +8309,76 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + ws@^7.4.6: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== +xhr-request-promise@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" + integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== + dependencies: + xhr-request "^1.1.0" + +xhr-request@^1.0.1, xhr-request@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr@^2.0.4, xhr@^2.3.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" + integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== + dependencies: + global "~4.4.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xmlhttprequest@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.2: +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== @@ -5618,6 +8393,14 @@ yargs-parser@20.2.4: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA== + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" @@ -5646,6 +8429,26 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + integrity sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA== + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" diff --git a/packages/subgraph/CHANGELOG.md b/packages/subgraph/CHANGELOG.md new file mode 100644 index 00000000..ee9f278f --- /dev/null +++ b/packages/subgraph/CHANGELOG.md @@ -0,0 +1,12 @@ +# Aragon OSx Subgraph + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.0.0 + +### Added + +- Copied files from [aragon/osx commit 19f4c4](https://github.com/aragon/osx/commit/19f4c42b5ae86b10b3a9cbbcaca6af504b69b0d2) diff --git a/packages/subgraph/manifest/subgraph.placeholder.yaml b/packages/subgraph/manifest/subgraph.placeholder.yaml index 2de5289f..c69d99e0 100644 --- a/packages/subgraph/manifest/subgraph.placeholder.yaml +++ b/packages/subgraph/manifest/subgraph.placeholder.yaml @@ -32,7 +32,7 @@ dataSources: {{/dataSources.PluginSetupProcessors}} # templates templates: - # Plugin (package) + # Plugin - name: Plugin kind: ethereum/contract network: {{network}} @@ -46,9 +46,18 @@ templates: - Dao abis: - name: Plugin - file: $PLUGIN_MODULE/contracts/artifacts/src/MyPlugin.sol/MyPlugin.json + file: $PLUGIN_MODULE/contracts/artifacts/src/Multisig.sol/Multisig.json eventHandlers: - - event: NumberStored(uint256) - handler: handleNumberStored - file: ./src/plugin/plugin.ts - + - event: MembersAdded(address[]) + handler: handleMembersAdded + - event: MembersRemoved(address[]) + handler: handleMembersRemoved + - event: Approved(indexed uint256,indexed address) + handler: handleApproved + - event: ProposalCreated(indexed uint256,indexed address,uint64,uint64,bytes,(address,uint256,bytes)[],uint256) + handler: handleProposalCreated + - event: ProposalExecuted(indexed uint256) + handler: handleProposalExecuted + - event: MultisigSettingsUpdated(bool,indexed uint16) + handler: handleMultisigSettingsUpdated + file: ./src/plugin/plugin.ts \ No newline at end of file diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index 6fd0d40e..bc4571ed 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -1,5 +1,5 @@ { - "name": "@aragon/osx-plugin-template-subgraph", + "name": "@aragon/multisig-plugin-subgraph", "version": "1.0.0", "license": "AGPL-3.0-or-later", "scripts": { diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index bb175125..d5471f61 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -5,6 +5,78 @@ type DaoPlugin @entity { dao: Bytes! pluginAddress: Bytes! - "Set plugin specific related data below:" - number: BigInt + "Plugin specific data:" + proposalCount: BigInt + proposals: [MultisigProposal!]! @derivedFrom(field: "plugin") + members: [MultisigApprover!]! @derivedFrom(field: "plugin") + + # multisig settings + minApprovals: Int + onlyListed: Boolean +} + +interface IProposal { + id: ID! # package + proposalId + dao: Bytes! #Before: Dao! // TODO remove this comment + creator: Bytes! + metadata: String + actions: [Action!]! @derivedFrom(field: "proposal") + allowFailureMap: BigInt! + failureMap: BigInt + executed: Boolean! + createdAt: BigInt! + startDate: BigInt! + endDate: BigInt! + executionTxHash: Bytes +} + +type Action @entity { + id: ID! + to: Bytes! + value: BigInt! + data: Bytes! + dao: Bytes! #Before: Dao! // TODO remove this comment + proposal: IProposal! + execResult: Bytes +} + +type MultisigApprover @entity { + id: ID! # plugin_address + member_address + address: String # address as string to facilitate filtering by address on the UI + proposals: [MultisigProposalApprover!]! @derivedFrom(field: "approver") + plugin: DaoPlugin! +} + +type MultisigProposalApprover @entity(immutable: true) { + "ApproverProposal for Many-to-Many" + id: ID! # approver + proposal + approver: MultisigApprover! + proposal: MultisigProposal! + createdAt: BigInt! +} + +type MultisigProposal implements IProposal @entity { + id: ID! # plugin + proposalId + dao: Bytes! #Before: Dao! // TODO remove this comment + actions: [Action!]! @derivedFrom(field: "proposal") + allowFailureMap: BigInt! + failureMap: BigInt + plugin: DaoPlugin! #Before: MultisigPlugin! // TODO remove this comment + pluginProposalId: BigInt! + creator: Bytes! + metadata: String + createdAt: BigInt! + startDate: BigInt! + endDate: BigInt! + creationBlockNumber: BigInt! + snapshotBlock: BigInt! + minApprovals: Int! + approvals: Int + approvalReached: Boolean! + isSignaling: Boolean! + executed: Boolean! + executionDate: BigInt + executionBlockNumber: BigInt + executionTxHash: Bytes + approvers: [MultisigProposalApprover!]! @derivedFrom(field: "proposal") } diff --git a/packages/subgraph/scripts/import-plugin-repo.ts b/packages/subgraph/scripts/import-plugin-repo.ts index 8f9d655c..8ee3ae6a 100644 --- a/packages/subgraph/scripts/import-plugin-repo.ts +++ b/packages/subgraph/scripts/import-plugin-repo.ts @@ -7,23 +7,16 @@ const rootDir = path.join(__dirname, '../../../'); // Adjust the path as necessa dotenv.config({path: path.join(rootDir, '.env')}); // Extract Repo address from the production-network-deployments.json -function extractAndWriteAddressToTS(jsonPath: string): void { - // Read the production-network-deployments.json file - const aragonDeploymentsInfo = JSON.parse(fs.readFileSync(jsonPath, 'utf8')); - - // Get the network from environment variables +function writeAddressToTS(): void { const network = process.env.SUBGRAPH_NETWORK_NAME; - - // Check if the network is defined in aragonDeploymentsInfo - if (!network || !aragonDeploymentsInfo[network]) { - throw new Error( - `Network '${network}' not found in production-network-deployments.json` - ); + if (network !== 'sepolia') { + throw 'The plugin repo address has been hardcoded only for sepolia for now.'; } + const sepoliaAddr = '0x9e7956C8758470dE159481e5DD0d08F8B59217A2'; // Start the Map creation code with the specific network address const tsContent: string[] = [ - `export const PLUGIN_REPO_ADDRESS = '${aragonDeploymentsInfo[network].address}';`, + `export const PLUGIN_REPO_ADDRESS = '${sepoliaAddr}';`, ]; const outputDir = path.join(__dirname, '../imported'); @@ -42,8 +35,4 @@ function extractAndWriteAddressToTS(jsonPath: string): void { ); } -const aragonDeploymentsInfoPath = path.join( - rootDir, - 'production-network-deployments.json' -); -extractAndWriteAddressToTS(aragonDeploymentsInfoPath); +writeAddressToTS(); diff --git a/packages/subgraph/src/plugin/plugin.ts b/packages/subgraph/src/plugin/plugin.ts index aa004d71..7aaac782 100644 --- a/packages/subgraph/src/plugin/plugin.ts +++ b/packages/subgraph/src/plugin/plugin.ts @@ -1,24 +1,223 @@ -import {DaoPlugin} from '../../generated/schema'; -import {NumberStored} from '../../generated/templates/Plugin/Plugin'; -import {generatePluginInstallationEntityId} from '@aragon/osx-commons-subgraph'; -import {Address, dataSource} from '@graphprotocol/graph-ts'; +import { + Action, + DaoPlugin, + MultisigProposal, + MultisigApprover, + MultisigProposalApprover, +} from '../../generated/schema'; +import { + ProposalCreated, + ProposalExecuted, + MembersAdded, + MembersRemoved, + Plugin, + Approved, + MultisigSettingsUpdated, +} from '../../generated/templates/Plugin/Plugin'; +import { + generateActionEntityId, + generateEntityIdFromAddress, + generatePluginEntityId, + generateProposalEntityId, +} from '@aragon/osx-commons-subgraph'; +import {Address, dataSource, store} from '@graphprotocol/graph-ts'; -export function handleNumberStored(event: NumberStored): void { - const pluginAddress = event.address; +export function handleProposalCreated(event: ProposalCreated): void { + let pluginProposalId = event.params.proposalId; + let pluginAddress = event.address; + let proposalEntityId = generateProposalEntityId( + pluginAddress, + pluginProposalId + ); + let pluginEntityId = generatePluginEntityId(pluginAddress); - const context = dataSource.context(); - const daoId = context.getString('daoAddress'); + let proposalEntity = new MultisigProposal(proposalEntityId); - const installationId = generatePluginInstallationEntityId( - Address.fromString(daoId), - pluginAddress - ); + let context = dataSource.context(); + let daoAddr = Address.fromHexString(context.getString('daoAddress')); + + proposalEntity.dao = daoAddr; + proposalEntity.plugin = pluginEntityId; + proposalEntity.pluginProposalId = pluginProposalId; + proposalEntity.creator = event.params.creator; + proposalEntity.metadata = event.params.metadata.toString(); + proposalEntity.createdAt = event.block.timestamp; + proposalEntity.creationBlockNumber = event.block.number; + proposalEntity.startDate = event.params.startDate; + proposalEntity.endDate = event.params.endDate; + proposalEntity.allowFailureMap = event.params.allowFailureMap; + + let contract = Plugin.bind(pluginAddress); + + let proposal = contract.try_getProposal(pluginProposalId); + if (!proposal.reverted) { + proposalEntity.executed = proposal.value.value0; + proposalEntity.approvals = proposal.value.value1; + + // ProposalParameters + let parameters = proposal.value.value2; + proposalEntity.minApprovals = parameters.minApprovals; + proposalEntity.snapshotBlock = parameters.snapshotBlock; + proposalEntity.approvalReached = false; + + // Actions + let actions = proposal.value.value3; + for (let index = 0; index < actions.length; index++) { + const action = actions[index]; + + let actionId = generateActionEntityId(proposalEntityId, index); + + let actionEntity = new Action(actionId); + actionEntity.to = action.to; + actionEntity.value = action.value; + actionEntity.data = action.data; + actionEntity.dao = daoAddr; + actionEntity.proposal = proposalEntityId; + actionEntity.save(); + } + proposalEntity.isSignaling = actions.length == 0; + } + + proposalEntity.save(); - if (installationId) { - const pluginEntity = DaoPlugin.load(installationId); - if (pluginEntity) { - pluginEntity.number = event.params.number; + // update vote length + let pluginEntity = DaoPlugin.load(pluginEntityId); + if (pluginEntity) { + let voteLength = contract.try_proposalCount(); + if (!voteLength.reverted) { + pluginEntity.proposalCount = voteLength.value; pluginEntity.save(); } } } +// TODO Begin - Move somewhere else +export function generateVoterEntityId( + memberEntityId: string, + proposalId: string +): string { + return [memberEntityId, proposalId].join('_'); +} + +export function generateMemberEntityId( + pluginAddress: Address, + memberAddress: Address +): string { + return [ + generateEntityIdFromAddress(pluginAddress), + generateEntityIdFromAddress(memberAddress), + ].join('_'); +} +// TODO End - Move somewhere else + +export function handleApproved(event: Approved): void { + let memberAddress = event.params.approver; + let pluginAddress = event.address; + let memberEntityId = generateMemberEntityId(pluginAddress, memberAddress); + let pluginProposalId = event.params.proposalId; + let proposalEntityId = generateProposalEntityId( + event.address, + pluginProposalId + ); + let approverProposalId = generateVoterEntityId( + memberEntityId, + proposalEntityId + ); + + let approverProposalEntity = + MultisigProposalApprover.load(approverProposalId); + if (!approverProposalEntity) { + approverProposalEntity = new MultisigProposalApprover(approverProposalId); + approverProposalEntity.approver = memberEntityId; + approverProposalEntity.proposal = proposalEntityId; + } + approverProposalEntity.createdAt = event.block.timestamp; + approverProposalEntity.save(); + + // update count + let proposalEntity = MultisigProposal.load(proposalEntityId); + if (proposalEntity) { + let contract = Plugin.bind(pluginAddress); + let proposal = contract.try_getProposal(pluginProposalId); + + if (!proposal.reverted) { + let approvals = proposal.value.value1; + proposalEntity.approvals = approvals; + + // calculate if proposal is executable + let minApprovalsStruct = proposal.value.value2; + + if ( + approvals >= minApprovalsStruct.minApprovals && + !proposalEntity.approvalReached + ) { + proposalEntity.approvalReached = true; + } + + proposalEntity.save(); + } + } +} + +export function handleProposalExecuted(event: ProposalExecuted): void { + let pluginProposalId = event.params.proposalId; + let proposalEntityId = generateProposalEntityId( + event.address, + pluginProposalId + ); + + let proposalEntity = MultisigProposal.load(proposalEntityId); + if (proposalEntity) { + proposalEntity.approvalReached = false; + proposalEntity.executed = true; + proposalEntity.executionDate = event.block.timestamp; + proposalEntity.executionBlockNumber = event.block.number; + proposalEntity.executionTxHash = event.transaction.hash; + proposalEntity.save(); + } +} + +export function handleMembersAdded(event: MembersAdded): void { + const members = event.params.members; + for (let index = 0; index < members.length; index++) { + const memberAddress = members[index]; + const pluginEntityId = generatePluginEntityId(event.address); + const memberEntityId = [pluginEntityId, memberAddress.toHexString()].join( + '_' + ); + + let approverEntity = MultisigApprover.load(memberEntityId); + if (!approverEntity) { + approverEntity = new MultisigApprover(memberEntityId); + approverEntity.address = memberAddress.toHexString(); + approverEntity.plugin = pluginEntityId; + approverEntity.save(); + } + } +} + +export function handleMembersRemoved(event: MembersRemoved): void { + const members = event.params.members; + for (let index = 0; index < members.length; index++) { + const memberAddress = members[index]; + const pluginEntityId = generatePluginEntityId(event.address); + const memberEntityId = [pluginEntityId, memberAddress.toHexString()].join( + '_' + ); + + const approverEntity = MultisigApprover.load(memberEntityId); + if (approverEntity) { + store.remove('MultisigApprover', memberEntityId); + } + } +} + +export function handleMultisigSettingsUpdated( + event: MultisigSettingsUpdated +): void { + let pluginEntity = DaoPlugin.load(generatePluginEntityId(event.address)); + if (pluginEntity) { + pluginEntity.onlyListed = event.params.onlyListed; + pluginEntity.minApprovals = event.params.minApprovals; + pluginEntity.save(); + } +} diff --git a/packages/subgraph/tests/plugin/plugin.test.ts b/packages/subgraph/tests/plugin/plugin.test.ts index 14db4cc4..cf45b2a9 100644 --- a/packages/subgraph/tests/plugin/plugin.test.ts +++ b/packages/subgraph/tests/plugin/plugin.test.ts @@ -1,18 +1,63 @@ -import {DaoPlugin} from '../../generated/schema'; -import {handleNumberStored} from '../../src/plugin/plugin'; -import {CONTRACT_ADDRESS, DAO_ADDRESS} from '../utils/constants'; -import {createNewNumberStoredEvent} from '../utils/events'; -import {generatePluginInstallationEntityId} from '@aragon/osx-commons-subgraph'; -import {Address, DataSourceContext} from '@graphprotocol/graph-ts'; +import {MultisigApprover} from '../../generated/schema'; +import { + handleMembersAdded, + handleApproved, + handleProposalExecuted, + handleMembersRemoved, + handleProposalCreated, + handleMultisigSettingsUpdated, + generateMemberEntityId, + generateVoterEntityId, +} from '../../src/plugin/plugin'; +import { + ADDRESS_ONE, + ADDRESS_TWO, + DAO_TOKEN_ADDRESS, + CONTRACT_ADDRESS, + STRING_DATA, + DAO_ADDRESS, + PLUGIN_PROPOSAL_ID, + SNAPSHOT_BLOCK, + ONE, + TWO, + PROPOSAL_ENTITY_ID, + START_DATE, + END_DATE, + ALLOW_FAILURE_MAP, +} from '../utils/constants'; +import { + createNewMembersAddedEvent, + createNewApprovedEvent, + createNewProposalExecutedEvent, + createNewMembersRemovedEvent, + createNewProposalCreatedEvent, + getProposalCountCall, + createMultisigProposalEntityState, + createGetProposalCall, + createNewMultisigSettingsUpdatedEvent, + createMultisigPluginState, +} from '../utils/events'; +import { + generatePluginEntityId, + generateProposalEntityId, + createDummyAction, +} from '@aragon/osx-commons-subgraph'; +import {Address, BigInt, DataSourceContext} from '@graphprotocol/graph-ts'; import { - assert, afterEach, + assert, beforeEach, clearStore, - test, - describe, dataSourceMock, -} from 'matchstick-as'; + describe, + test, +} from 'matchstick-as/assembly/index'; + +let actions = [createDummyAction(DAO_TOKEN_ADDRESS, '0', '0x00000000')]; + +const pluginAddress = Address.fromString(CONTRACT_ADDRESS); +const pluginEntityId = generatePluginEntityId(pluginAddress); +const pluginProposalId = BigInt.fromString(PLUGIN_PROPOSAL_ID); describe('Plugin', () => { beforeEach(function () { @@ -25,36 +70,464 @@ describe('Plugin', () => { clearStore(); }); - describe('NumberStored Event', () => { - test('it should store the correct number emitted from the event', () => { - const daoAddress = Address.fromString(DAO_ADDRESS); - const pluginAddress = Address.fromString(CONTRACT_ADDRESS); + describe('ProposalCreated', () => { + test('Run Multisig (handleProposalCreated) mappings with mock event', () => { + // create state + createMultisigPluginState(); + + // create calls + getProposalCountCall(CONTRACT_ADDRESS, '1'); + createGetProposalCall( + CONTRACT_ADDRESS, + PLUGIN_PROPOSAL_ID, + false, + + // ProposalParameters + START_DATE, + END_DATE, + ONE, + SNAPSHOT_BLOCK, + + // approvals + ONE, + + actions, + + ALLOW_FAILURE_MAP + ); + + // create event + let event = createNewProposalCreatedEvent( + PLUGIN_PROPOSAL_ID, + ADDRESS_ONE, + START_DATE, + END_DATE, + STRING_DATA, + actions, + ALLOW_FAILURE_MAP, + CONTRACT_ADDRESS + ); + + // handle event + handleProposalCreated(event); + + let proposalEntityId = generateProposalEntityId( + pluginAddress, + pluginProposalId + ); + + // checks + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'id', + proposalEntityId + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'dao', + DAO_ADDRESS + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'plugin', + pluginEntityId + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'pluginProposalId', + PLUGIN_PROPOSAL_ID + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'creator', + ADDRESS_ONE + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'startDate', + START_DATE + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'endDate', + END_DATE + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'metadata', + STRING_DATA + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'createdAt', + event.block.timestamp.toString() + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'creationBlockNumber', + event.block.number.toString() + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'snapshotBlock', + SNAPSHOT_BLOCK + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'minApprovals', + ONE + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'approvals', + ONE + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'executed', + 'false' + ); + assert.fieldEquals( + 'MultisigProposal', + proposalEntityId, + 'allowFailureMap', + ALLOW_FAILURE_MAP + ); + + // check MultisigPlugin + assert.fieldEquals( + 'MultisigPlugin', + Address.fromString(CONTRACT_ADDRESS).toHexString(), + 'proposalCount', + '1' + ); + }); + }); + + describe('Approved', () => { + test('Run Multisig (handleApproved) mappings with mock event', () => { + // create state + let proposal = createMultisigProposalEntityState( + PROPOSAL_ENTITY_ID, + DAO_ADDRESS, + CONTRACT_ADDRESS, + ADDRESS_ONE + ); + + // create calls + createGetProposalCall( + CONTRACT_ADDRESS, + PLUGIN_PROPOSAL_ID, + false, + + // ProposalParameters + START_DATE, + END_DATE, + TWO, // minApprovals + SNAPSHOT_BLOCK, + + // approvals + ONE, + + actions, + ALLOW_FAILURE_MAP + ); + + // create event + let event = createNewApprovedEvent( + PLUGIN_PROPOSAL_ID, + ADDRESS_ONE, + CONTRACT_ADDRESS + ); + + handleApproved(event); + + // checks + const memberAddress = Address.fromString(ADDRESS_ONE); + + const memberEntityId = generateMemberEntityId( + pluginAddress, + memberAddress + ); + + const voterEntityId = generateVoterEntityId(memberEntityId, proposal.id); + // check proposalVoter + assert.fieldEquals( + 'MultisigProposalApprover', + voterEntityId, + 'id', + voterEntityId + ); + assert.fieldEquals( + 'MultisigProposalApprover', + voterEntityId, + 'approver', + memberEntityId + ); + assert.fieldEquals( + 'MultisigProposalApprover', + voterEntityId, + 'proposal', + proposal.id + ); + assert.fieldEquals( + 'MultisigProposalApprover', + voterEntityId, + 'createdAt', + event.block.timestamp.toString() + ); + + // check proposal + assert.fieldEquals('MultisigProposal', proposal.id, 'approvals', ONE); + assert.fieldEquals( + 'MultisigProposal', + proposal.id, + 'approvalReached', + 'false' + ); + + // create 2nd approve, to test approvals + // create calls + createGetProposalCall( + CONTRACT_ADDRESS, + PLUGIN_PROPOSAL_ID, + false, + + // ProposalParameters + START_DATE, + END_DATE, + TWO, // minApprovals + SNAPSHOT_BLOCK, + + // approvals + TWO, + + actions, + ALLOW_FAILURE_MAP + ); + + // create event + let event2 = createNewApprovedEvent( + PLUGIN_PROPOSAL_ID, + ADDRESS_TWO, + CONTRACT_ADDRESS + ); + + handleApproved(event2); + + // Check + assert.fieldEquals('MultisigProposal', proposal.id, 'approvals', TWO); + assert.fieldEquals( + 'MultisigProposal', + proposal.id, + 'approvalReached', + 'true' + ); + }); + }); + + describe('ProposalExecuted', () => { + test('Run Multisig (handleProposalExecuted) mappings with mock event', () => { + // create state + createMultisigProposalEntityState( + PROPOSAL_ENTITY_ID, + DAO_ADDRESS, + CONTRACT_ADDRESS, + ADDRESS_ONE + ); + + // create event + let event = createNewProposalExecutedEvent('0', CONTRACT_ADDRESS); + + // handle event + handleProposalExecuted(event); - const installationId = generatePluginInstallationEntityId( - daoAddress, - pluginAddress + // checks + assert.fieldEquals( + 'MultisigProposal', + PROPOSAL_ENTITY_ID, + 'id', + PROPOSAL_ENTITY_ID ); - if (!installationId) { - throw new Error('Failed to get installationId'); + assert.fieldEquals( + 'MultisigProposal', + PROPOSAL_ENTITY_ID, + 'executed', + 'true' + ); + assert.fieldEquals( + 'MultisigProposal', + PROPOSAL_ENTITY_ID, + 'executionDate', + event.block.timestamp.toString() + ); + assert.fieldEquals( + 'MultisigProposal', + PROPOSAL_ENTITY_ID, + 'executionBlockNumber', + event.block.number.toString() + ); + assert.fieldEquals( + 'MultisigProposal', + PROPOSAL_ENTITY_ID, + 'executionTxHash', + event.transaction.hash.toHexString() + ); + }); + }); + + describe('MembersAdded', () => { + test('Run Multisig (handleMembersAdded) mappings with mock event', () => { + let userArray = [ + Address.fromString(ADDRESS_ONE), + Address.fromString(ADDRESS_TWO), + ]; + + // create event + let event = createNewMembersAddedEvent(userArray, CONTRACT_ADDRESS); + + // handle event + handleMembersAdded(event); + + // checks + let memberId = + Address.fromString(CONTRACT_ADDRESS).toHexString() + + '_' + + userArray[0].toHexString(); + + assert.fieldEquals('MultisigApprover', memberId, 'id', memberId); + assert.fieldEquals( + 'MultisigApprover', + memberId, + 'address', + userArray[0].toHexString() + ); + assert.fieldEquals( + 'MultisigApprover', + memberId, + 'plugin', + Address.fromString(CONTRACT_ADDRESS).toHexString() + ); + }); + }); + + describe('MembersRemoved', () => { + test('Run Multisig (handleMembersRemoved) mappings with mock event', () => { + // create state + let memberAddresses = [ + Address.fromString(ADDRESS_ONE), + Address.fromString(ADDRESS_TWO), + ]; + + for (let index = 0; index < memberAddresses.length; index++) { + const user = memberAddresses[index].toHexString(); + const pluginId = Address.fromString(CONTRACT_ADDRESS).toHexString(); + let memberId = pluginId + '_' + user; + let userEntity = new MultisigApprover(memberId); + userEntity.plugin = Address.fromString(CONTRACT_ADDRESS).toHexString(); + userEntity.save(); } - // Create state - let daoPlugin = new DaoPlugin(installationId!); - daoPlugin.dao = daoAddress; - daoPlugin.pluginAddress = pluginAddress; - daoPlugin.save(); - const number = '5'; + // checks + let memberId1 = + Address.fromString(CONTRACT_ADDRESS).toHexString() + + '_' + + memberAddresses[0].toHexString(); + let memberId2 = + Address.fromString(CONTRACT_ADDRESS).toHexString() + + '_' + + memberAddresses[1].toHexString(); + + assert.fieldEquals('MultisigApprover', memberId1, 'id', memberId1); + assert.fieldEquals('MultisigApprover', memberId2, 'id', memberId2); + + // create event + let event = createNewMembersRemovedEvent( + [memberAddresses[1]], + CONTRACT_ADDRESS + ); + + // handle event + handleMembersRemoved(event); - const event = createNewNumberStoredEvent( - number, - pluginAddress.toHexString() + // checks + assert.fieldEquals('MultisigApprover', memberId1, 'id', memberId1); + assert.notInStore('MultisigApprover', memberId2); + }); + }); + + describe('MultisigSettingsUpdated', () => { + test('Run Multisig (handleMultisigSettingsUpdated) mappings with mock event', () => { + // create state + let entityID = createMultisigPluginState().id; + + // create event + let onlyListed = true; + let minApproval = '5'; + + let event = createNewMultisigSettingsUpdatedEvent( + onlyListed, + minApproval, + CONTRACT_ADDRESS + ); + + // handle event + handleMultisigSettingsUpdated(event); + + // checks + assert.fieldEquals( + 'MultisigPlugin', + entityID, + 'onlyListed', + `${onlyListed}` + ); + assert.fieldEquals( + 'MultisigPlugin', + entityID, + 'minApprovals', + minApproval ); - handleNumberStored(event); + // create event + onlyListed = false; + minApproval = '4'; + + event = createNewMultisigSettingsUpdatedEvent( + onlyListed, + minApproval, + CONTRACT_ADDRESS + ); - assert.fieldEquals('DaoPlugin', installationId!, 'id', installationId!); - assert.fieldEquals('DaoPlugin', installationId!, 'number', number); - assert.entityCount('DaoPlugin', 1); + // handle event + handleMultisigSettingsUpdated(event); + + // checks + assert.fieldEquals( + 'MultisigPlugin', + entityID, + 'onlyListed', + `${onlyListed}` + ); + assert.fieldEquals( + 'MultisigPlugin', + entityID, + 'minApprovals', + minApproval + ); }); }); }); diff --git a/packages/subgraph/tests/utils/constants.ts b/packages/subgraph/tests/utils/constants.ts index f0ea51a9..87ddb69d 100644 --- a/packages/subgraph/tests/utils/constants.ts +++ b/packages/subgraph/tests/utils/constants.ts @@ -2,6 +2,12 @@ // ADDRESS_ZERO to ADDRESS_SIX: Dummy Ethereum addresses for various test cases. // DAO_ADDRESS: A placeholder address for a DAO instance. // CONTRACT_ADDRESS: A placeholder address for a contract instance. +import { + generatePluginEntityId, + generateProposalEntityId, +} from '@aragon/osx-commons-subgraph'; +import {Address, BigInt} from '@graphprotocol/graph-ts'; + // PLUGIN_SETUP_ID: A mock identifier for a plugin setup in test simulations. export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'; export const ADDRESS_ONE = '0x0000000000000000000000000000000000000001'; @@ -14,3 +20,34 @@ export const DAO_ADDRESS = '0x00000000000000000000000000000000000000da'; export const CONTRACT_ADDRESS = '0x00000000000000000000000000000000000000Ad'; export const PLUGIN_SETUP_ID = '0xfb3fd2c4cd4e19944dd3f8437e67476240cd9e3efb2294ebd10c59c8f1d6817c'; + +// TODO Added from OSX. This must be refactored. +export const ZERO = '0'; +export const ONE = '1'; +export const TWO = '2'; +export const THREE = '3'; + +export const PLUGIN_PROPOSAL_ID = ZERO; + +/// +export const PROPOSAL_ENTITY_ID = generateProposalEntityId( + Address.fromString(CONTRACT_ADDRESS), + BigInt.fromString(PLUGIN_PROPOSAL_ID) +); + +export const MIN_PROPOSER_VOTING_POWER = ZERO; +export const START_DATE = '1644851000'; +export const END_DATE = '1644852000'; +export const SNAPSHOT_BLOCK = '100'; + +export const STRING_DATA = 'Some String Data ...'; + +// Use 1 for testing as default value is anyways 0 and test might succeed even though it shouldn't. +export const ALLOW_FAILURE_MAP = '1'; + +export const DAO_TOKEN_ADDRESS = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; +export const CREATED_AT = ONE; + +export const PLUGIN_ENTITY_ID = generatePluginEntityId( + Address.fromString(CONTRACT_ADDRESS) +); diff --git a/packages/subgraph/tests/utils/events/plugin.ts b/packages/subgraph/tests/utils/events/plugin.ts index 58df89f7..e3e8912e 100644 --- a/packages/subgraph/tests/utils/events/plugin.ts +++ b/packages/subgraph/tests/utils/events/plugin.ts @@ -1,22 +1,323 @@ -import {NumberStored} from '../../../generated/templates/Plugin/Plugin'; -import {Address, BigInt, ethereum} from '@graphprotocol/graph-ts'; -import {newMockEvent} from 'matchstick-as'; +import {DaoPlugin, MultisigProposal} from '../../../generated/schema'; +import { + ProposalCreated, + Approved, + ProposalExecuted, + MembersAdded, + MembersRemoved, + MultisigSettingsUpdated, +} from '../../../generated/templates/Plugin/Plugin'; +import { + ADDRESS_ONE, + DAO_ADDRESS, + PROPOSAL_ENTITY_ID, + PLUGIN_PROPOSAL_ID, + CONTRACT_ADDRESS, + SNAPSHOT_BLOCK, + CREATED_AT, + TWO, + START_DATE, + END_DATE, + ALLOW_FAILURE_MAP, + ZERO, + THREE, + PLUGIN_ENTITY_ID, +} from '../constants'; +import {Address, BigInt, Bytes, ethereum} from '@graphprotocol/graph-ts'; +import {createMockedFunction, newMockEvent} from 'matchstick-as'; -export function createNewNumberStoredEvent( - number: string, +// events + +export function createNewProposalCreatedEvent( + proposalId: string, + creator: string, + startDate: string, + endDate: string, + metadata: string, + actions: ethereum.Tuple[], + allowFailureMap: string, contractAddress: string -): NumberStored { - let createNumberStoredEvent = changetype(newMockEvent()); +): ProposalCreated { + let createProposalCreatedEvent = changetype(newMockEvent()); - createNumberStoredEvent.address = Address.fromString(contractAddress); - createNumberStoredEvent.parameters = []; + createProposalCreatedEvent.address = Address.fromString(contractAddress); + createProposalCreatedEvent.parameters = []; let proposalIdParam = new ethereum.EventParam( - 'number', - ethereum.Value.fromSignedBigInt(BigInt.fromString(number)) + 'proposalId', + ethereum.Value.fromSignedBigInt(BigInt.fromString(proposalId)) + ); + let creatorParam = new ethereum.EventParam( + 'creator', + ethereum.Value.fromAddress(Address.fromString(creator)) + ); + let startDateParam = new ethereum.EventParam( + 'startDate', + ethereum.Value.fromSignedBigInt(BigInt.fromString(startDate)) + ); + let endDateParam = new ethereum.EventParam( + 'endDate', + ethereum.Value.fromSignedBigInt(BigInt.fromString(endDate)) + ); + let metadataParam = new ethereum.EventParam( + 'metadata', + ethereum.Value.fromBytes(Bytes.fromUTF8(metadata)) + ); + let actionsParam = new ethereum.EventParam( + 'actions', + ethereum.Value.fromTupleArray(actions) + ); + let allowFailureMapParam = new ethereum.EventParam( + 'allowFailureMap', + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(allowFailureMap)) + ); + + createProposalCreatedEvent.parameters.push(proposalIdParam); + createProposalCreatedEvent.parameters.push(creatorParam); + createProposalCreatedEvent.parameters.push(startDateParam); + createProposalCreatedEvent.parameters.push(endDateParam); + createProposalCreatedEvent.parameters.push(metadataParam); + createProposalCreatedEvent.parameters.push(actionsParam); + createProposalCreatedEvent.parameters.push(allowFailureMapParam); + + return createProposalCreatedEvent; +} + +export function createNewApprovedEvent( + proposalId: string, + approver: string, + contractAddress: string +): Approved { + let createApprovedEvent = changetype(newMockEvent()); + + createApprovedEvent.address = Address.fromString(contractAddress); + createApprovedEvent.parameters = []; + + let proposalIdParam = new ethereum.EventParam( + 'proposalId', + ethereum.Value.fromSignedBigInt(BigInt.fromString(proposalId)) + ); + let approverParam = new ethereum.EventParam( + 'approver', + ethereum.Value.fromAddress(Address.fromString(approver)) + ); + + createApprovedEvent.parameters.push(proposalIdParam); + createApprovedEvent.parameters.push(approverParam); + + return createApprovedEvent; +} + +export function createNewProposalExecutedEvent( + proposalId: string, + contractAddress: string +): ProposalExecuted { + let createProposalExecutedEvent = changetype( + newMockEvent() + ); + + createProposalExecutedEvent.address = Address.fromString(contractAddress); + createProposalExecutedEvent.parameters = []; + + let proposalIdParam = new ethereum.EventParam( + 'proposalId', + ethereum.Value.fromSignedBigInt(BigInt.fromString(proposalId)) + ); + + createProposalExecutedEvent.parameters.push(proposalIdParam); + + return createProposalExecutedEvent; +} + +export function createNewMembersAddedEvent( + addresses: Address[], + contractAddress: string +): MembersAdded { + let newMembersAddedEvent = changetype(newMockEvent()); + + newMembersAddedEvent.address = Address.fromString(contractAddress); + newMembersAddedEvent.parameters = []; + + let usersParam = new ethereum.EventParam( + 'users', + ethereum.Value.fromAddressArray(addresses) + ); + + newMembersAddedEvent.parameters.push(usersParam); + + return newMembersAddedEvent; +} + +export function createNewMembersRemovedEvent( + addresses: Address[], + contractAddress: string +): MembersRemoved { + let newMembersRemovedEvent = changetype(newMockEvent()); + + newMembersRemovedEvent.address = Address.fromString(contractAddress); + newMembersRemovedEvent.parameters = []; + + let usersParam = new ethereum.EventParam( + 'users', + ethereum.Value.fromAddressArray(addresses) + ); + + newMembersRemovedEvent.parameters.push(usersParam); + + return newMembersRemovedEvent; +} + +export function createNewMultisigSettingsUpdatedEvent( + onlyListed: boolean, + minApprovals: string, + contractAddress: string +): MultisigSettingsUpdated { + let newProposalSettingsUpdatedEvent = changetype( + newMockEvent() + ); + + newProposalSettingsUpdatedEvent.address = Address.fromString(contractAddress); + newProposalSettingsUpdatedEvent.parameters = []; + + let onlyListedParam = new ethereum.EventParam( + 'onlyListed', + ethereum.Value.fromBoolean(onlyListed) ); - createNumberStoredEvent.parameters.push(proposalIdParam); + let minApprovalsParam = new ethereum.EventParam( + 'minApprovals', + ethereum.Value.fromSignedBigInt(BigInt.fromString(minApprovals)) + ); + + newProposalSettingsUpdatedEvent.parameters.push(onlyListedParam); + newProposalSettingsUpdatedEvent.parameters.push(minApprovalsParam); + + return newProposalSettingsUpdatedEvent; +} + +// calls + +export function getProposalCountCall( + contractAddress: string, + returns: string +): void { + createMockedFunction( + Address.fromString(contractAddress), + 'proposalCount', + 'proposalCount():(uint256)' + ) + .withArgs([]) + .returns([ethereum.Value.fromSignedBigInt(BigInt.fromString(returns))]); +} + +export function createGetProposalCall( + contractAddress: string, + proposalId: string, + executed: boolean, + + startDate: string, + endDate: string, + minApprovals: string, + snapshotBlock: string, + + approvals: string, + + actions: ethereum.Tuple[], + allowFailureMap: string +): void { + let parameters = new ethereum.Tuple(); + + parameters.push( + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(minApprovals)) + ); + parameters.push( + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(snapshotBlock)) + ); + parameters.push( + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(startDate)) + ); + parameters.push( + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(endDate)) + ); + + createMockedFunction( + Address.fromString(contractAddress), + 'getProposal', + 'getProposal(uint256):(bool,uint16,(uint16,uint64,uint64,uint64),(address,uint256,bytes)[],uint256)' + ) + .withArgs([ + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(proposalId)), + ]) + .returns([ + ethereum.Value.fromBoolean(executed), + + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(approvals)), + + // ProposalParameters + ethereum.Value.fromTuple(parameters), + + ethereum.Value.fromTupleArray(actions), + + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(allowFailureMap)), + ]); +} + +// state + +export function createMultisigPluginState( + entityID: string = PLUGIN_ENTITY_ID, + dao: string = DAO_ADDRESS, + pluginAddress: string = CONTRACT_ADDRESS, + proposalCount: string = ZERO, + minApprovals: string = THREE, + onlyListed: boolean = false +): DaoPlugin { + let multisigPlugin = new DaoPlugin(entityID); + multisigPlugin.dao = Bytes.fromHexString(dao); + multisigPlugin.pluginAddress = Bytes.fromHexString(pluginAddress); + multisigPlugin.proposalCount = BigInt.fromString(proposalCount); + multisigPlugin.minApprovals = parseInt(minApprovals) as i32; + multisigPlugin.onlyListed = onlyListed; + multisigPlugin.save(); + + return multisigPlugin; +} + +export function createMultisigProposalEntityState( + entityID: string = PROPOSAL_ENTITY_ID, + dao: string = DAO_ADDRESS, + plugin: string = CONTRACT_ADDRESS, + creator: string = ADDRESS_ONE, + pluginProposalId: string = PLUGIN_PROPOSAL_ID, + minApprovals: string = TWO, + startDate: string = START_DATE, + endDate: string = END_DATE, + executable: boolean = false, + executed: boolean = false, + allowFailureMap: string = ALLOW_FAILURE_MAP, + + snapshotBlock: string = SNAPSHOT_BLOCK, + + createdAt: string = CREATED_AT, + creationBlockNumber: BigInt = new BigInt(0) +): MultisigProposal { + let multisigProposal = new MultisigProposal(entityID); + multisigProposal.dao = Address.fromHexString(dao); //Address.fromString(dao).toHexString(); + multisigProposal.plugin = Address.fromString(plugin).toHexString(); + multisigProposal.pluginProposalId = BigInt.fromString(pluginProposalId); + multisigProposal.creator = Address.fromString(creator); + multisigProposal.startDate = BigInt.fromString(startDate); + multisigProposal.endDate = BigInt.fromString(endDate); + multisigProposal.approvalReached = executable; + multisigProposal.isSignaling = false; + multisigProposal.executed = executed; + multisigProposal.snapshotBlock = BigInt.fromString(snapshotBlock); + multisigProposal.minApprovals = BigInt.fromString(minApprovals).toI32(); + multisigProposal.allowFailureMap = BigInt.fromString(allowFailureMap); + multisigProposal.createdAt = BigInt.fromString(createdAt); + multisigProposal.creationBlockNumber = creationBlockNumber; + + multisigProposal.save(); - return createNumberStoredEvent; + return multisigProposal; }