diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml new file mode 100644 index 00000000..aaf2dadf --- /dev/null +++ b/.github/workflows/slither.yml @@ -0,0 +1,49 @@ +name: Slither Analysis + +on: + push: + branches: + - '*' + pull_request: + branches: [develop, master] + +jobs: + analyze: + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - uses: actions/setup-python@v4 + with: + python-version: "3.10.6" + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Install poetry requirements + run: > + curl -sSL https://install.python-poetry.org | python - && + poetry install + + - name: Run slither + run: > + poetry run slither . --sarif results.sarif --fail-none --compile-force-framework foundry + + - name: Check results.sarif presence + id: results + if: always() + shell: bash + run: > + test -f results.sarif && + echo 'value=present' >> $GITHUB_OUTPUT || + echo 'value=not' >> $GITHUB_OUTPUT + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v2 + if: ${{ always() && steps.results.outputs.value == 'present' }} + with: + sarif_file: results.sarif diff --git a/.github/workflows/verify-bytecode.yml b/.github/workflows/verify-bytecode.yml deleted file mode 100644 index cf905584..00000000 --- a/.github/workflows/verify-bytecode.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Verify deployed contracts' bytecode - -on: - pull_request: - branches: - - "master" - -jobs: - assert-bytecode: - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v3 - with: - persist-credentials: false - - - name: Install poetry - run: pipx install poetry - - - name: Setup python - uses: actions/setup-python@v4 - with: - python-version-file: .python-version - cache: poetry - - - name: Install python dependencies - run: poetry install - - - name: Compile contracts - run: poetry run brownie compile - - - name: Verify bytecode of contracts - uses: lidofinance/action-verify-bytecode@master - with: - file: artifacts.json diff --git a/.gitignore b/.gitignore index 1b071dc7..583cd84c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ reports/ .vscode .pytest_cache node_modules -/contracts_flattened \ No newline at end of file +/contracts_flattened +logs \ No newline at end of file diff --git a/.python-version b/.python-version index 0a590336..ac957df8 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.9.10 +3.10.6 diff --git a/README.md b/README.md index 8b185e83..9336026f 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ ## Problem -Lido DAO governance currently relies on Aragon voting model. This means DAO approves or rejects proposals via direct governance token voting. Though transparent and reliable, it is not a convenient way to make decisions only affecting small groups of Lido DAO members. Besides, direct token voting doesn't exactly reflect all the decision making processes within the Lido DAO and is often used only to rubberstamp an existing consensus. -There are a few natural sub-governance groups within the DAO, e.g. validators commitee, financial operations team and LEGO commitee. Every day they need to take routine actions only related to their field of expertise. The decisions they make hardly ever spark any debate in the comunity, and votings on such decisions often struggle to attract wider DAO attention and thus, to pass. +Lido DAO governance currently relies on Aragon voting model. This means DAO approves or rejects proposals via direct governance token voting. Though transparent and reliable, it is not a convenient way to make decisions only affecting small groups of Lido DAO members. Besides, direct token voting doesn't exactly reflect all the decision making processes within the Lido DAO and is often used only to rubber-stamp an existing consensus. +There are a few natural sub-governance groups within the DAO, e.g. validators committee, financial operations team and LEGO committee. Every day they need to take routine actions only related to their field of expertise. The decisions they make hardly ever spark any debate in the community, and votings on such decisions often struggle to attract wider DAO attention and thus, to pass. ## Solution @@ -23,7 +23,7 @@ See [specification.md](https://github.com/lidofinance/easy-track/blob/master/spe ## EVMScript Factory Requirements -### Methods Compability +### Methods Compatibility **Every EVMScript factory must implement [`IEVMScriptFactory`](https://github.com/lidofinance/easy-track/blob/master/contracts/interfaces/IEVMScriptFactory.sol) interface.** @@ -33,7 +33,7 @@ Methods from this interface are used by EasyTrack at the motion lifecycle. **Every action done by EasyTrack must be allowed to do also by Aragon Voting.** -This requirement fills automatically in cases when easy tracks do actions provided by the Aragon application. But for contracts outside the Aragon ecosystem access to Voting must be provided explicitly. To grant such access you can use role-based control access contracts from the OpenZeppelin package. To see an example of how this pattern was used in EVMScript factories see the `RewardPrgoramsRegistry.sol` contract. +This requirement fills automatically in cases when easy tracks do actions provided by the Aragon application. But for contracts outside the Aragon ecosystem access to Voting must be provided explicitly. To grant such access you can use role-based control access contracts from the OpenZeppelin package. To see an example of how this pattern was used in EVMScript factories see the `RewardProgramsRegistry.sol` contract. ### Onchain EVMScript calldata decoding @@ -55,18 +55,15 @@ Permissions for EVMScript factory must contain only methods used by generated EV ## Project Setup -To use the tools that this project provides, please pull the repository from GitHub and install its dependencies as follows. It is recommended to use a Python virtual environment. +To use the tools that this project provides, please pull the repository from GitHub and install its dependencies as follows. ```bash git clone https://github.com/lidofinance/easy-track cd easy-track -npm install - -# in case of pyyaml installation issue, it should be installed manually -# see issue for details https://github.com/yaml/pyyaml/issues/601 -poetry run pip install "cython<3.0" pyyaml==5.4.1 --no-build-isolation +yarn install poetry install +poetry run brownie networks import network-config.yaml True poetry shell ``` @@ -130,19 +127,26 @@ Script requires next ENV variables to be set: ## Tests +Set infura project ID +```bash +export WEB3_INFURA_PROJECT_ID= +``` + The fastest way to run the tests is: ```bash -brownie test +brownie test --network mainnet-fork ``` Run tests with coverage and gas profiling: ```bash -brownie test --coverage --gas +brownie test --network mainnet-fork --coverage --gas ``` -#### Coverage notes +### Coverage notes + +#### Immutable issues Current brownie version has problems with coverage reports for some contracts. Contracts which use `immutable` variables don't get on the resulting report. Details can be found in this [issue](https://github.com/eth-brownie/brownie/issues/1087). Easy Track uses `immutable` modifier in next contracts: @@ -153,5 +157,19 @@ Current brownie version has problems with coverage reports for some contracts. C - [RemoveRewardProgram.sol](https://github.com/lidofinance/easy-track/blob/a72858804481009f2e09508ffbf93d8a4aee6c84/contracts/EVMScriptFactories/RemoveRewardProgram.sol#L23) - [TopUpLegoProgram.sol](https://github.com/lidofinance/easy-track/blob/a72858804481009f2e09508ffbf93d8a4aee6c84/contracts/EVMScriptFactories/TopUpLegoProgram.sol#L26) - [TopUpRewardProgram.sol](https://github.com/lidofinance/easy-track/blob/a72858804481009f2e09508ffbf93d8a4aee6c84/contracts/EVMScriptFactories/TopUpRewardPrograms.sol#L27) +- [TopUpAllowedRecipients.sol](https://github.com/lidofinance/easy-track/blob/522ae893f6c03516354a8d1950b29b3203adae52/contracts/EVMScriptFactories/TopUpAllowedRecipients.sol#L29) + +The workaround for the coverage problem is removing the `immutable` modifier from the above contracts. Without modifier above contracts will be listed in the coverage report. + +#### No-branching issue + +Another brownie issue is that some functions do not get into the coverage report. For example `decodeEVMScriptCallData` of `RemoveAllowedRecipient` contract: + +``` + contract: RemoveAllowedRecipient - 100.0% + RemoveAllowedRecipient.createEVMScript - 100.0% +``` + +Although in brownie coverage report explorer (`brownie gui`) in statements section the function body is highlighted green, which means it is covered. -The workaround for the coverage problem is removing the `immutable` modifier from the above contracts. Without modifier above contracts will be listed in the coverage report +It seems such functions are not reflected in % coverage report, due to absence of branching in the function body. Adding dummy branching brings them to the report. diff --git a/artifacts.json b/artifacts.json index 0c62f193..b86fbd97 100644 --- a/artifacts.json +++ b/artifacts.json @@ -79,5 +79,306 @@ "name": "TopUpRewardPrograms", "address": "0x54058ee0E0c87Ad813C002262cD75B98A7F59218", "txHash": "0xdc88901783832ea7d78dcd0145030d9e7d1f45261b9dfe83fca541de056bb2e0" + }, + { + "artifactPath": "build/contracts/AddNodeOperators.json", + "sourcePath": "contracts/EVMScriptFactories/AddNodeOperators.sol", + "name": "AddNodeOperators", + "address": "0xcAa3AF7460E83E665EEFeC73a7a542E5005C9639", + "txHash": "0xbb5dfa188b864b8fdb969bde660a02d219d454e2a5265bb89e3f3c7dfd3336cc" + }, + { + "artifactPath": "build/contracts/ActivateNodeOperators.json", + "sourcePath": "contracts/EVMScriptFactories/ActivateNodeOperators.sol", + "name": "ActivateNodeOperators", + "address": "0xCBb418F6f9BFd3525CE6aADe8F74ECFEfe2DB5C8", + "txHash": "0x85d072e4171bcd62a185018e3463b544397dcba740816d089f48bd0745770dcd" + }, + { + "artifactPath": "build/contracts/DeactivateNodeOperators.json", + "sourcePath": "contracts/EVMScriptFactories/DeactivateNodeOperators.sol", + "name": "DeactivateNodeOperators", + "address": "0x8B82C1546D47330335a48406cc3a50Da732672E7", + "txHash": "0x14e288e2c3830aaa8e06a2bd8ab2f85dcc6dcd84df88ad9e928f10ce8be8152c" + }, + { + "artifactPath": "build/contracts/SetVettedValidatorsLimits.json", + "sourcePath": "contracts/EVMScriptFactories/SetVettedValidatorsLimits.sol", + "name": "SetVettedValidatorsLimits", + "address": "0xD75778b855886Fc5e1eA7D6bFADA9EB68b35C19D", + "txHash": "0xe8e6c5c7d3fd183d7513cf30425e1d6373cc1144fba019dab11ba5f83b23dec4" + }, + { + "artifactPath": "build/contracts/SetNodeOperatorNames.json", + "sourcePath": "contracts/EVMScriptFactories/SetNodeOperatorNames.sol", + "name": "SetNodeOperatorNames", + "address": "0x7d509BFF310d9460b1F613e4e40d342201a83Ae4", + "txHash": "0x85c453fa256e4bc0378c2a2e8acf981f4ad136cbd9c3011a330addef9938e55d" + }, + { + "artifactPath": "build/contracts/SetNodeOperatorRewardAddresses.json", + "sourcePath": "contracts/EVMScriptFactories/SetNodeOperatorRewardAddresses.sol", + "name": "SetNodeOperatorRewardAddresses", + "address": "0x589e298964b9181D9938B84bB034C3BB9024E2C0", + "txHash": "0xfe9faec5e6913ab05b3b6653535d861aa94c9cb60f69305394f8a195bf478deb" + }, + { + "artifactPath": "build/contracts/UpdateTargetValidatorLimits.json", + "sourcePath": "contracts/EVMScriptFactories/UpdateTargetValidatorLimits.sol", + "name": "UpdateTargetValidatorLimits", + "address": "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C", + "txHash": "0xbdc7864ef2fb24e7b5ce954c82f652c9cd2f9be8014deb17810ec6b3462628d1" + }, + { + "artifactPath": "build/contracts/ChangeNodeOperatorManagers.json", + "sourcePath": "contracts/EVMScriptFactories/ChangeNodeOperatorManagers.sol", + "name": "ChangeNodeOperatorManagers", + "address": "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D", + "txHash": "0x51e051105f14f5924089188994cb89acca6b78535efeb42c0c53171b22a36d97" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsBuilder.json", + "sourcePath": "contracts/AllowedRecipientsBuilder.sol", + "name": "AllowedRecipientsBuilder (single token)", + "address": "0x958e0D946D014F377421a53AB5f9180d4485e63B", + "txHash": "0x9ed8b63f91519bc6362ebb4625a0845f69255227f47305712a31909787ea3067" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsBuilder.json", + "sourcePath": "contracts/AllowedRecipientsBuilder.sol", + "name": "AllowedRecipientsBuilder (multi token)", + "address": "0x334D6eDc13F63728b39e6A6D04A7Bbd5D6A9B9FF", + "txHash": "0x0ebc3c7fb01bbc64591d97c0b57b1c3746b1f0c6403198df0798c7d5496336d1" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsFactory.json", + "sourcePath": "contracts/AllowedRecipientsFactory.sol", + "name": "AllowedRecipientsFactory (single token)", + "address": "0x83E976758B7AB1bb676A4fEA073Fa0E2A807642B", + "txHash": "0xcf1309c337848d0e7fb58e5ece73749ca5dbc261b77d253e077aa006ff0434ec" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsFactory.json", + "sourcePath": "contracts/AllowedRecipientsFactory.sol", + "name": "AllowedRecipientsFactory (multi token)", + "address": "0xEe60C6ebC91237d334230b12263E26EE3b480ec4", + "txHash": "0x9e1e54d9259ee76454a745aeb4ff44b35fb2cad4592bb289e38dbf75e27dfe5f" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry LOL (ex.reWARDS) stETH", + "address": "0x48c4929630099b217136b64089E8543dB0E5163a", + "txHash": "0xac7ccec0c11a204636ca2a660d73bfca772eaacd5d7076061b44d73324c509c8" + }, + { + "artifactPath": "build/contracts/AddAllowedRecipient.json", + "sourcePath": "contracts/EVMScriptFactories/AddAllowedRecipient.sol", + "name": "AddAllowedRecipient LOL (ex.reWARDS) stETH", + "address": "0x935cb3366Faf2cFC415B2099d1F974Fd27202b77", + "txHash": "0xac7ccec0c11a204636ca2a660d73bfca772eaacd5d7076061b44d73324c509c8" + }, + { + "artifactPath": "build/contracts/RemoveAllowedRecipient.json", + "sourcePath": "contracts/EVMScriptFactories/RemoveAllowedRecipient.sol", + "name": "RemoveAllowedRecipient LOL (ex.reWARDS) stETH", + "address": "0x22010d1747CaFc370b1f1FBBa61022A313c5693b", + "txHash": "0xac7ccec0c11a204636ca2a660d73bfca772eaacd5d7076061b44d73324c509c8" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients LOL (ex.reWARDS) stETH", + "address": "0x1F2b79FE297B7098875930bBA6dd17068103897E", + "txHash": "0xac7ccec0c11a204636ca2a660d73bfca772eaacd5d7076061b44d73324c509c8" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry Rewards Share stETH", + "address": "0xdc7300622948a7AdaF339783F6991F9cdDD79776", + "txHash": "0x71527ca532b0664ad504c59b15fa5b0167788839cd59bd0aa8ba492afbedab41" + }, + { + "artifactPath": "build/contracts/AddAllowedRecipient.json", + "sourcePath": "contracts/EVMScriptFactories/AddAllowedRecipient.sol", + "name": "AddAllowedRecipient Rewards Share stETH", + "address": "0x1F809D2cb72a5Ab13778811742050eDa876129b6", + "txHash": "0x71527ca532b0664ad504c59b15fa5b0167788839cd59bd0aa8ba492afbedab41" + }, + { + "artifactPath": "build/contracts/RemoveAllowedRecipient.json", + "sourcePath": "contracts/EVMScriptFactories/RemoveAllowedRecipient.sol", + "name": "RemoveAllowedRecipient Rewards Share stETH", + "address": "0xd30Dc38EdEfc21875257e8A3123503075226E14B", + "txHash": "0x71527ca532b0664ad504c59b15fa5b0167788839cd59bd0aa8ba492afbedab41" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients Rewards Share stETH", + "address": "0xbD08f9D6BF1D25Cc7407E4855dF1d46C2043B3Ea", + "txHash": "0x71527ca532b0664ad504c59b15fa5b0167788839cd59bd0aa8ba492afbedab41" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry Gas Supply stETH", + "address": "0x49d1363016aA899bba09ae972a1BF200dDf8C55F", + "txHash": "0x77e7bb75d64e9689ceba72233b612d65fe9b4000a408b5105addcd4e3257809a" + }, + { + "artifactPath": "build/contracts/AddAllowedRecipient.json", + "sourcePath": "contracts/EVMScriptFactories/AddAllowedRecipient.sol", + "name": "AddAllowedRecipient Gas Supply stETH", + "address": "0x48c135Ff690C2Aa7F5B11C539104B5855A4f9252", + "txHash": "0x77e7bb75d64e9689ceba72233b612d65fe9b4000a408b5105addcd4e3257809a" + }, + { + "artifactPath": "build/contracts/RemoveAllowedRecipient.json", + "sourcePath": "contracts/EVMScriptFactories/RemoveAllowedRecipient.sol", + "name": "RemoveAllowedRecipient Gas Supply stETH", + "address": "0x7E8eFfAb3083fB26aCE6832bFcA4C377905F97d7", + "txHash": "0x77e7bb75d64e9689ceba72233b612d65fe9b4000a408b5105addcd4e3257809a" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients Gas Supply stETH", + "address": "0x200dA0b6a9905A377CF8D469664C65dB267009d1", + "txHash": "0x77e7bb75d64e9689ceba72233b612d65fe9b4000a408b5105addcd4e3257809a" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry LEGO LDO", + "address": "0x97615f72c3428A393d65A84A3ea6BBD9ad6C0D74", + "txHash": "0x97b0e1b31123310b72ccf6ac3f03ecff3b81b25c6c5425768c54384a1ed13e51" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients LEGO LDO", + "address": "0x00caAeF11EC545B192f16313F53912E453c91458", + "txHash": "0x97b0e1b31123310b72ccf6ac3f03ecff3b81b25c6c5425768c54384a1ed13e51" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry RCC stETH", + "address": "0xAAC4FcE2c5d55D1152512fe5FAA94DB267EE4863", + "txHash": "0xc95a28bb440d9a00819241c13b20195462dd836545e1921814581c7ce31d1eb4" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients RCC stETH", + "address": "0xcD42Eb8a5db5a80Dc8f643745528DD77cf4C7D35", + "txHash": "0xc95a28bb440d9a00819241c13b20195462dd836545e1921814581c7ce31d1eb4" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry PML stETH", + "address": "0x7b9B8d00f807663d46Fb07F87d61B79884BC335B", + "txHash": "0x5e33e5de2e6806d2cf7d546c5dcc42e870a51021385b82913f709ab9d45cbcc5" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients PML stETH", + "address": "0xc5527396DDC353BD05bBA578aDAa1f5b6c721136", + "txHash": "0x5e33e5de2e6806d2cf7d546c5dcc42e870a51021385b82913f709ab9d45cbcc5" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry ATC stETH", + "address": "0xd3950eB3d7A9B0aBf8515922c0d35D13e85a2c91", + "txHash": "0x82254bba8285a9b924b651a85c93573b7f72736b1974b4e74141653c24a0f7c3" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients ATC stETH", + "address": "0x87b02dF27cd6ec128532Add7C8BC19f62E6f1fB9", + "txHash": "0x82254bba8285a9b924b651a85c93573b7f72736b1974b4e74141653c24a0f7c3" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry TRP LDO", + "address": "0x231Ac69A1A37649C6B06a71Ab32DdD92158C80b8", + "txHash": "0x9c11c1e1ea3738009dfe2be823f0264c4607a6b73e6ef5983d0c00670fe1b662" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients TRP LDO", + "address": "0xBd2b6dC189EefD51B273F5cb2d99BA1ce565fb8C", + "txHash": "0x9c11c1e1ea3738009dfe2be823f0264c4607a6b73e6ef5983d0c00670fe1b662" + }, + { + "artifactPath": "build/contracts/AllowedTokensRegistry.json", + "sourcePath": "contracts/AllowedTokensRegistry.sol", + "name": "AllowedTokensRegistry", + "address": "0x4AC40c34f8992bb1e5E856A448792158022551ca", + "txHash": "0xb29ee752d1b66a293be52a96b78e01408e1ad84f0d047128b953ba55887640be" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry LEGO stablecoins", + "address": "0xb0FE4D300334461523D9d61AaD90D0494e1Abb43", + "txHash": "0xc859903d85df03bd6ea6a88d94c3498da87cd68f412773c56734d2a5a7158541" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients LEGO stablecoins", + "address": "0x6AB39a8Be67D9305799c3F8FdFc95Caf3150d17c", + "txHash": "0x6a5113c019d8a28a090caff7e08fc0d64030f3bd9e1429ccf4ae13c8e2a65524" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry RCC stablecoins", + "address": "0xDc1A0C7849150f466F07d48b38eAA6cE99079f80", + "txHash": "0x533b0d9a817bc4e7e23af7025bf0294d7e072ac87d697a318b598362b8a81878" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients RCC stablecoins", + "address": "0x75bDecbb6453a901EBBB945215416561547dfDD4", + "txHash": "0x66b3ec391322bb5a4e96e66c0d5126595f5111667ab0fa6e9489f64670410c6e" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry PML stablecoins", + "address": "0xDFfCD3BF14796a62a804c1B16F877Cf7120379dB", + "txHash": "0x87c3d12d05e02a039132b201a2783cb272c0d78139d89ea7e3e283aefb0308ed" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients PML stablecoins", + "address": "0x92a27C4e5e35cFEa112ACaB53851Ec70e2D99a8D", + "txHash": "0xb39089364f80192ac51d6dbe0518af8f70df9ffb0762bd61578f2735f89d5bdd" + }, + { + "artifactPath": "build/contracts/AllowedRecipientsRegistry.json", + "sourcePath": "contracts/AllowedRecipientsRegistry.sol", + "name": "AllowedRecipientsRegistry ATC stablecoins", + "address": "0xe07305F43B11F230EaA951002F6a55a16419B707", + "txHash": "0x6f1412ba3084b922cd72a291b19a1dd927a5fc9528913f2dc2dac00e068ea9ae" + }, + { + "artifactPath": "build/contracts/TopUpAllowedRecipients.json", + "sourcePath": "contracts/EVMScriptFactories/TopUpAllowedRecipients.sol", + "name": "TopUpAllowedRecipients ATC stablecoins", + "address": "0x1843Bc35d1fD15AbE1913b9f72852a79457C42Ab", + "txHash": "0xf1dd7b5ab88c606cae77197b66c0d2eba916d915d3a735dfe3830a391aa55865" } ] diff --git a/brownie-config.yaml b/brownie-config.yaml index 3518915c..4bb262d3 100644 --- a/brownie-config.yaml +++ b/brownie-config.yaml @@ -1,24 +1,21 @@ networks: default: development development: - cmd: ganache-cli + cmd: ./ganache.sh host: http://127.0.0.1 timeout: 120 cmd_settings: - port: 8545 - gas_limit: 12000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: mainnet - -dependencies: - - OpenZeppelin/openzeppelin-contracts@4.3.2 - -# path remapping to support OpenZepplin imports with NPM-style path + accounts: 10 + evm_version: berlin + fork: mainnet + gas_limit: 30000000 + mnemonic: brownie + port: 8545 compiler: solc: version: 0.8.6 + remappings: + - OpenZeppelin/openzeppelin-contracts@4.3.2=./dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2 reports: exclude_paths: - contracts/test/**/* diff --git a/bytecode-verificator/SHA256SUMS b/bytecode-verificator/SHA256SUMS new file mode 100644 index 00000000..19d0fd51 --- /dev/null +++ b/bytecode-verificator/SHA256SUMS @@ -0,0 +1,6 @@ +d619d4f5d8fd988bc63262407e749e905ccc8d8ab1ccf0280da1d12b918894ce ./compilers/solc-darwin-0.8.9 +f851f11fad37496baabaf8d6cb5c057ca0d9754fddb7a351ab580d7fd728cb94 ./compilers/solc-linux-0.8.9 +86ee99f64fc7e36bfa046169b6a4d4c10eb35017ed11e0c970f01223b2f5db36 ./compilers/solc-darwin-0.8.6 +abd5c4f3f262bc3ed7951b968c63f98e83f66d9a5c3568ab306eac49250aec3e ./compilers/solc-linux-0.8.6 +7034c4048bc713d5c14cdd6681953c736e2adbdb9174f8bfbfb6a097109ffaaa ./compilers/solc-darwin-0.4.24 +665675b9e0431c2572d59d6a7112afbdc752732ea0ce9aecf1a1855f28e02a09 ./compilers/solc-linux-0.4.24 diff --git a/bytecode-verificator/binary.dat b/bytecode-verificator/binary.dat new file mode 100644 index 00000000..d88d7508 Binary files /dev/null and b/bytecode-verificator/binary.dat differ diff --git a/bytecode-verificator/bytecode_verificator.sh b/bytecode-verificator/bytecode_verificator.sh new file mode 100755 index 00000000..cfc05fdf --- /dev/null +++ b/bytecode-verificator/bytecode_verificator.sh @@ -0,0 +1,501 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +if [[ "${TRACE-0}" == "1" ]]; then + set -o xtrace +fi + +################################ +# Bytecode verification script # +################################ + +RED='\033[0;31m' +ORANGE='\033[0;33m' +GREEN='\033[0;32m' +NC='\033[0m' + +zero_padding=$(printf '%0.1s' "0"{1..64}) +placeholder_padding=$(printf '%0.1s' "-"{1..64}) + +# Prerequisite executables +prerequisites=(jq yarn awk curl shasum uname bc nc) + +# Environment vailable required +envs=(ETHERSCAN_TOKEN) + +# Commandline args required +cmdargs=(solc_version remote_rpc_url etherscan_api_url contract config_json) +sha256sum='shasum -a 256' + +# Vars +constructor_calldata="" +contract_config_name="" +local_rpc_url="" +# Fork PID of Ganache +fork_pid=0 +local_rpc_port=7776 +local_rpc_url=http://127.0.0.1:${local_rpc_port} + +function show_help() { + cat <<-_EOF_ + Bytecode verificator + + CLI tool to validate contract bytecode at remote rpc node, etherscan and bytecode deployed from local source code + + $0 [--solc-version ] [--remote-rpc-url ] [--etherscan-api-url ] [--contract ] [--config-json ] [--constructor-calldata ] [-h|--help] + + Options: + --solc-version SOLC-VERSION version of solidity to compile contract with (e.g. 0.4.24, 0.8.9) + --remote-rpc-url REMOTE-RPC-URL Ethereum node URL that contains the comparating contract bytecode. e.g. https://mainnet.infura.io/v3/\$WEB3_INFURA_PROJECT_ID + --etherscan-api ETHERSCAN-API-URL Etherscan API URL e.g. https://api.etherscan.io/api + --contract CONTRACT Contract name from config file. (e.g. app:lido, stakingRouter, lidoLocator ...) + --config-json CONFIG-JSON Path to JSON file. Artifacts of deployment (e.g './deployed-mainnet.json') + --constructor-calldata DATA (optional) Calldata that will be used for local contract deployment. Will be encoded from config file if does not provided. (hex data with no 0x prefix) + -h, --help Prints help. +_EOF_ +} + +# Entry point +main() { + SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) + cd "${SCRIPT_DIR}" + + check_root + check_prerequisites + check_envs + + parse_cmd_args "$@" + check_compiler + [[ "${local_ganache:-unset}" == "unset" ]] && start_fork + + [[ "${skip_compilation:-unset}" == "unset" ]] && compile_contract + deploy_contract_on_fork + compare_bytecode +} + +# Service functions + +function check_root() { + if ((EUID == 0)); then + _err "This script must NOT be run as root" + fi +} + +function check_prerequisites() { + for p in "${prerequisites[@]}"; do + [[ -x "$(command -v "$p")" ]] || { _err "$p app is required but not found"; } + done +} + +function check_envs() { + for e in "${envs[@]}"; do + [[ "${!e:+isset}" == "isset" ]] || { _err "${e} env var is required but is not set"; } + done +} + +function parse_cmd_args() { + + while [[ $# -gt 0 ]]; do + case $1 in + --solc-version) + solc_version="$2" + [[ "$solc_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { _err "Invalid solc version: $solc_version"; } + shift + shift + ;; + --remote-rpc-url) + remote_rpc_url="$2" + [[ "$remote_rpc_url" =~ ^http ]] || { _err "Invalid remote rpc URL: $remote_rpc_url"; } + shift + shift + ;; + --etherscan-api-url) + etherscan_api_url="$2" + [[ "$etherscan_api_url" =~ ^https ]] || { _err "Invalid Etherscan API URL: $remote_rpc_url"; } + shift + shift + ;; + --contract) + contract="$2" + shift + shift + ;; + --config-json) + config_json="$2" + [[ -f $config_json ]] || { _err "config file ${config_json} does not exist"; } + shift + shift + ;; + --constructor-calldata) + constructor_calldata="$2" + [[ "$constructor_calldata" =~ ^[0-9A-Fa-f]+$ ]] || { _err "Invalid calldata: $constructor_calldata"; } + shift + shift + ;; + --skip-compilation) + skip_compilation=true + shift + ;; + --local-ganache) + local_ganache=true + shift + ;; + --help | -h) + show_help + exit 0 + ;; + --* | -*) + _err "Unknown option \"$1\"" + ;; + esac + done + + for arg in "${cmdargs[@]}"; do + if [ "${!arg:+isset}" != "isset" ]; then + _err "argument '--${arg//_/-}' is empty" + fi + done +} + +function check_compiler() { + platform=$(uname | awk '{print tolower($0)}') + + solc=./compilers/solc-$platform-$solc_version + + if ! [ -x "$(command -v "$solc")" ]; then + _err "$solc could not be found or is not executable" + fi + + echo -e "Platform: ${ORANGE}$platform${NC}" + echo -e "Compiler version: ${ORANGE}$solc_version${NC}" + echo -e "Compiler binary: ${ORANGE}$solc${NC}" + + compilerSha256Sum=$($sha256sum "$solc") + grep -q "$compilerSha256Sum" ./SHA256SUMS || { _err "\"$solc\" has unrecognized checksum (local)"; } + + [[ $platform == "darwin" ]] && platform="macosx" + + github_sha256=$(curl -sS https://binaries.soliditylang.org/$platform-amd64/list.json | jq -r ".builds | .[] | select(.version==\"$solc_version\").sha256") + [[ "$github_sha256 $solc" == "0x$compilerSha256Sum" ]] || { _err "$solc has unrecognized checksum (github)"; } + + checksum=$(echo -e "$compilerSha256Sum" | awk '{print $1;}') + echo -e "Compiler checksum ${ORANGE}$checksum${GREEN} is correct${NC}" +} + +function start_fork() { + local_fork_command=$( + cat <<-_EOF_ | xargs | sed 's/ / /g' + yarn ganache --chain.vmErrorsOnRPCResponse true + --wallet.totalAccounts 10 --chain.chainId 1 + --fork.url ${remote_rpc_url} + --miner.blockGasLimit 30000000 + --server.host 127.0.0.1 --server.port ${local_rpc_port} + --hardfork istanbul -d +_EOF_ + ) + + echo "Starting local fork \"${local_fork_command}\"" + (nc -vz 127.0.0.1 $local_rpc_port) &>/dev/null && kill -SIGTERM "$(lsof -t -i:$local_rpc_port)" + + $local_fork_command 1>>./logs 2>&1 & + fork_pid=$$ + echo "Ganache pid $fork_pid" + + sleep 10 +} + +function encode_address() { + echo "${1/0x/000000000000000000000000}" +} + +function encode_uint256() { + printf "%064X\n" "$1" +} + +function encode_bytes32() { + echo "${1/0x/}" +} + +function encode_bytes() { + local bytes_str + local data_length + local encoded_length + + bytes_str=$(sed -E 's/^0x(00)*//' <<<"$1") + data_length=$((${#bytes_str} / 2)) + encoded_length=0 + if [[ data_length -gt "0" ]]; then + encoded_length=$(bc <<<"(((${#bytes_str} - 1) / 64) + 1) * 64") + fi + bytes_str=$bytes_str$zero_padding + bytes_str=${bytes_str:0:$encoded_length} + echo "$(printf "%064X\n" "$data_length")$bytes_str" +} + +function encode_string() { + local string_bytes + local data_length + local encoded_length + + string_bytes=$(xxd -p <<<"$1" | sed 's/..$//') + data_length=$(bc <<<"${#string_bytes} / 2") + encoded_length=0 + if [[ data_length -gt "0" ]]; then + encoded_length=$(bc <<<"(((${#string_bytes} - 1) / 64) + 1) * 64") + fi + string_bytes=$string_bytes$zero_padding + string_bytes=${string_bytes:0:$encoded_length} + echo "$(printf "%064X\n" "$data_length")$string_bytes" +} + +function encode_array() { + local type=$1 + local array=$2 + local array_length + local encoded_data + encoded_data="" + + array_length=$(jq -r 'length' <<<"$array") + encoded_data="$encoded_data$(encode_uint256 "$(bc <<<"$array_length * 32")")" + if [[ $array_length -gt 0 ]]; then + for i in $(seq 0 "$(bc <<<"$array_length - 1")"); do + case $type in + address\[\]) encoded_data="$encoded_data$(encode_address "$(jq -r ".[$i]" <<<"$array")")" ;; + uint256\[\]) encoded_data="$encoded_data$(encode_uint256 "$(jq -r ".[$i]" <<<"$array")")" ;; + bytes32\[\]) encoded_data="$encoded_data$(encode_bytes32 "$(jq -r ".[$i]" <<<"$array")")" ;; + *) _err "Unknown constructor argument type '$type', use --constructor-calldata instead" ;; + esac + done + fi + echo "$encoded_data" +} + +function encode_tuple() { + local types=$1 + local args=$2 + local args_length + local encoded_data + encoded_data="" + + args_length=$(jq -r 'length' <<<"$types") + + for arg_index in $(seq 0 "$(bc <<<"$args_length - 1")"); do + local arg_type + local arg + + arg_type=$(jq -r ".[$arg_index]" <<<"$types") + arg=$(jq -r ".[$arg_index]" <<<"$args") + + case $arg_type in + address) encoded_data="$encoded_data$(encode_address "$arg")" ;; + uint256) encoded_data="$encoded_data$(encode_uint256 "$arg")" ;; + bytes32) encoded_data="$encoded_data$(encode_bytes32 "$arg")" ;; + *) _err "Unknown constructor argument type '$arg_type', use --constructor-calldata instead" ;; + esac + done + echo "$encoded_data" +} + +function endode_solidity_calldata_placeholder() { + local placeholder="$1$placeholder_padding" + echo "${placeholder:0:64}" +} + +function compile_contract() { + rm -rf "${PWD}/build" + cd "${PWD}/.." + ./bytecode-verificator/"$solc" contracts/**/*.sol contracts/*.sol -o ./bytecode-verificator/build --allow-paths "$PWD" --bin --overwrite --optimize --optimize-runs 200 1>>./logs 2>&1 + ./bytecode-verificator/"$solc" contracts/**/*.sol contracts/*.sol -o ./bytecode-verificator/build --allow-paths "$PWD" --abi --overwrite --optimize --optimize-runs 200 1>>./logs 2>&1 + cd - &>/dev/null +} + +function deploy_contract_on_fork() { + contract_config_name=$(_read_contract_config "$contract" contract) + contract_config_address=$(_read_contract_config "$contract" address) + + echo -e "Contract name: ${ORANGE}$contract_config_name${NC}" + echo -e "Contract address: ${ORANGE}$contract_config_address${NC}" + + if [[ "${constructor_calldata:-unset}" == "unset" ]]; then + local contract_abi + local constructor_abi + local arg_length + local constructor_config_args + local compl_data + + compl_data=() + contract_abi=$(cat ./build/"$contract_config_name".abi) + constructor_abi=$(jq -r '.[] | select(.type == "constructor") | .inputs ' <<<"$contract_abi") + arg_length=$(jq -r 'length' <<<"$constructor_abi") + + echo -e "Constructor args types: $(jq ".[].type" <<<"$constructor_abi")" + + constructor_config_args=$(_read_contract_config "$contract" constructorArgs) + + if [[ $arg_length -gt 0 ]]; then + for argument_index in $(seq 0 "$(bc <<<"$arg_length - 1")"); do + local arg_type + local arg + + arg_type=$(jq -r ".[$argument_index].type" <<<"$constructor_abi") + arg=$(jq -r ".[$argument_index]" <<<"$constructor_config_args") + + case $arg_type in + address) constructor_calldata="$constructor_calldata$(encode_address "$arg")" ;; + uint256) constructor_calldata="$constructor_calldata$(encode_uint256 "$arg")" ;; + bytes32) constructor_calldata="$constructor_calldata$(encode_bytes32 "$arg")" ;; + bytes) + constructor_calldata="$constructor_calldata$(endode_solidity_calldata_placeholder ${#compl_data[@]})" + compl_data+=("$(encode_bytes "$arg")") + ;; + string) + constructor_calldata="$constructor_calldata$(endode_solidity_calldata_placeholder ${#compl_data[@]})" + compl_data+=("$(encode_string "$arg")") + ;; + tuple) + args_types=$(jq -r ".[$argument_index].components | map(.type)" <<<"$constructor_abi") + constructor_calldata="$constructor_calldata$(encode_tuple "$args_types" "$arg")" + ;; + *[]) + constructor_calldata="$constructor_calldata$(endode_solidity_calldata_placeholder ${#compl_data[@]})" + compl_data+=("$(encode_array "$arg_type" "$arg")") + ;; + *) _err "Unknown constructor argument type '$arg_type', use --constructor-calldata instead" ;; + esac + done + + for index in "${!compl_data[@]}"; do + encoded_data_length=$(bc <<<"${#constructor_calldata} / 2") + constructor_calldata=$(sed -E "s/$(endode_solidity_calldata_placeholder "$index")/$(printf "%064X\n" "$encoded_data_length")/" <<<"$constructor_calldata${compl_data[$index]}") + done + fi + fi + + echo "Contract constructor encoded args: 0x$constructor_calldata" + + echo "Deploying compiled contract to local fork" + contract_bytecode=$(cat ./build/"$contract_config_name".bin) + deployment_bytecode="0x$contract_bytecode$constructor_calldata" + deployer_account=$(_get_account "$local_rpc_url" 0) + local_contract_address=$(_deploy_contract "$local_rpc_url" "$deployer_account" "$deployment_bytecode") + echo "Done" +} + +function compare_bytecode() { + local remote_code + local local_code + local etherscan_code + + echo "Retrieving contract bytecode from local rpc (Ganache)" + local_code=$(_get_code $local_rpc_url "$local_contract_address") + + echo -e "Retrieving contract bytecode from remote rpc ${remote_rpc_url}" + remote_code=$(_get_code "$remote_rpc_url" "$contract_config_address") + + echo "Retrieving contract bytecode from etherscan" + etherscan_code=$(_get_code_etherscan "$contract_config_address") + + echo "Replacing CBOR-encoded metadata" + # https://docs.soliditylang.org/en/v0.8.9/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode + remote_code=$(sed -E 's/a264697066735822[0-9a-f]{68}//' <<<"$remote_code") + local_code=$(sed -E 's/a264697066735822[0-9a-f]{68}//' <<<"$local_code") + etherscan_code=$(sed -E 's/a264697066735822[0-9a-f]{68}//' <<<"$etherscan_code") + + # https://docs.soliditylang.org/en/v0.4.24/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode + remote_code=$(sed -E 's/a165627a7a72305820[0-9a-f]{68}//' <<<"$remote_code") + local_code=$(sed -E 's/a165627a7a72305820[0-9a-f]{68}//' <<<"$local_code") + etherscan_code=$(sed -E 's/a165627a7a72305820[0-9a-f]{68}//' <<<"$etherscan_code") + + _print_checksum local_code + _print_checksum remote_code + _print_checksum etherscan_code + + echo "Comparing remote and local bytecode" + [[ "$local_code" == "$remote_code" ]] || { + mkdir -p ./verificator_diffs + + echo "" > ./verificator_diffs/"$contract"_local.bin; + while IFS='' read -r -d '' -n 2 char; do + echo -en "\x$char" >> ./verificator_diffs/"$contract"_local.bin; + done < <(printf %s "$local_code") + echo "" > ./verificator_diffs/"$contract"_remote.bin; + while IFS='' read -r -d '' -n 2 char; do + echo -en "\x$char" >> ./verificator_diffs/"$contract"_remote.bin; + done < <(printf %s "$remote_code") + + _err "local bytecode and remote bytecode is not equal. Bytecode saved in ./verificator_diffs/" + } + echo -e "${GREEN}Local bytecode matches with remote rpc${NC}" + + echo "Comparing etherscan and local bytecode" + [[ "$local_code" == "$etherscan_code" ]] || { _err "local bytecode and etherscan bytecode is not equal"; } + echo -e "${GREEN}Local bytecode matches with etherscan${NC}" +} + +# Internals + +_get_code() { + local rpc_url=$1 + local contract_address=$2 + + curl -sS -X POST -H "Content-Type: application/json" "$rpc_url" --data "{\"jsonrpc\": \"2.0\", \"id\": 42, \"method\": \"eth_getCode\", \"params\": [\"$contract_address\", \"latest\"]}" | jq -r '.result' +} + +_get_code_etherscan() { + local contract_address=$1 + curl -sS -G -d "address=$contract_address" -d "action=eth_getCode" -d "module=proxy" -d "tag=latest" -d "apikey=$ETHERSCAN_TOKEN" "$etherscan_api_url" | jq -r '.result' +} + +_get_account() { + local rpc_url=$1 + + curl -sS -X POST -H "Content-Type: application/json" "$rpc_url" --data '{"jsonrpc": "2.0", "id": 42, "method": "eth_accounts", "params": []}' | jq -r '.result[0]' +} + +_deploy_contract() { + local rpc_url=$1 + local deployer=$2 + local data=$3 + + tx_hash=$(curl -sS -X POST "$rpc_url" --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendTransaction\",\"params\":[{\"from\":\"$deployer\", \"to\":null, \"gas\": \"0x1312D00\", \"data\":\"$data\"}], \"id\":1}" -H 'Content-Type: application/json' | jq -r '.result') + + contract_address=$(curl -sS -X POST -H "Content-Type: application/json" "$rpc_url" --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\":[\"$tx_hash\"],\"id\":1}" | jq -r '.result.contractAddress') + + echo "$contract_address" +} + +_read_contract_config() { + local contract=$1 + local param=$2 + + jq -r ".\"$contract\".\"$param\"" <"$config_json" +} + +_print_checksum() { + + echo -e "${ORANGE}$1${NC} checksum: $(echo "${!1}" | $sha256sum)" +} + +_err() { + local message=$1 + + echo -e "${RED}Error:${NC} $message, aborting." >&2 + exit 1 +} + +# Intercept ctrl+C +trap ctrl_c INT +ctrl_c() { + if [[ "$fork_pid" -gt 0 ]]; then + echo "Stopping ganache" + kill -SIGTERM "$fork_pid" + fi + exit 0 +} + +# Run main +main "$@" +ctrl_c diff --git a/bytecode-verificator/compilers/solc-darwin-0.8.6 b/bytecode-verificator/compilers/solc-darwin-0.8.6 new file mode 100755 index 00000000..aa535423 Binary files /dev/null and b/bytecode-verificator/compilers/solc-darwin-0.8.6 differ diff --git a/bytecode-verificator/compilers/solc-linux-0.8.6 b/bytecode-verificator/compilers/solc-linux-0.8.6 new file mode 100755 index 00000000..49b0ef8e Binary files /dev/null and b/bytecode-verificator/compilers/solc-linux-0.8.6 differ diff --git a/contracts/AllowedRecipientsBuilder.sol b/contracts/AllowedRecipientsBuilder.sol new file mode 100644 index 00000000..3133a57a --- /dev/null +++ b/contracts/AllowedRecipientsBuilder.sol @@ -0,0 +1,339 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +interface IEasyTrack { + function evmScriptExecutor() external view returns (address); +} + +interface IAllowedRecipientsRegistry { + function addRecipient(address _recipient, string memory _title) external; + + function renounceRole(bytes32 role, address account) external; + + function isRecipientAllowed(address _recipient) external view returns (bool); + + function setLimitParameters(uint256 _limit, uint256 _periodDurationMonths) external; + + function getLimitParameters() external view returns (uint256, uint256); + + function updateSpentAmount(uint256 _payoutAmount) external; + + function spendableBalance() external view returns (uint256); + + function hasRole(bytes32 role, address account) external view returns (bool); + + function getAllowedRecipients() external view returns (address[] memory); + + function bokkyPooBahsDateTimeContract() external view returns (address); +} + +interface ITopUpAllowedRecipients { + function token() external view returns (address); + + function finance() external view returns (address); + + function easyTrack() external view returns (IEasyTrack); + + function trustedCaller() external view returns (address); + + function allowedRecipientsRegistry() external view returns (address); +} + +interface IAddAllowedRecipient { + function trustedCaller() external view returns (address); + + function allowedRecipientsRegistry() external view returns (address); +} + +interface IRemoveAllowedRecipient { + function trustedCaller() external view returns (address); + + function allowedRecipientsRegistry() external view returns (address); +} + +interface IAllowedRecipientsFactory { + function deployAllowedRecipientsRegistry( + address _admin, + address[] memory _addRecipientToAllowedListRoleHolders, + address[] memory _removeRecipientFromAllowedListRoleHolders, + address[] memory _setLimitParametersRoleHolders, + address[] memory _updateSpentAmountRoleHolders, + address bokkyPooBahsDateTimeContract + ) external returns (IAllowedRecipientsRegistry); + + function deployTopUpAllowedRecipients( + address _trustedCaller, + address _allowedRecipientsRegistry, + address _token, + address _finance, + IEasyTrack _easyTrack + ) external returns (ITopUpAllowedRecipients); + + function deployAddAllowedRecipient(address _trustedCaller, address _allowedRecipientsRegistry) + external + returns (IAddAllowedRecipient); + + function deployRemoveAllowedRecipient( + address _trustedCaller, + address _allowedRecipientsRegistry + ) external returns (IRemoveAllowedRecipient); +} + +contract AllowedRecipientsBuilder { + IEasyTrack public immutable easyTrack; + address public immutable finance; + address public immutable evmScriptExecutor; + address public immutable admin; + address public immutable bokkyPooBahsDateTimeContract; + IAllowedRecipientsFactory public immutable factory; + + bytes32 public constant ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE = + keccak256("ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE"); + bytes32 public constant REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE = + keccak256("REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE"); + bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; + bytes32 public constant SET_PARAMETERS_ROLE = keccak256("SET_PARAMETERS_ROLE"); + bytes32 public constant UPDATE_SPENT_AMOUNT_ROLE = keccak256("UPDATE_SPENT_AMOUNT_ROLE"); + + constructor( + IAllowedRecipientsFactory _factory, + address _admin, + IEasyTrack _easytrack, + address _finance, + address _bokkyPooBahsDateTimeContract + ) { + factory = _factory; + evmScriptExecutor = _easytrack.evmScriptExecutor(); + admin = _admin; + easyTrack = _easytrack; + finance = _finance; + bokkyPooBahsDateTimeContract = _bokkyPooBahsDateTimeContract; + } + + function deployAllowedRecipientsRegistry( + uint256 _limit, + uint256 _periodDurationMonths, + address[] memory _recipients, + string[] memory _titles, + uint256 _spentAmount, + bool _grantRightsToEVMScriptExecutor + ) public returns (IAllowedRecipientsRegistry registry) { + require(_recipients.length == _titles.length, "Recipients data length mismatch"); + require(_spentAmount <= _limit, "_spentAmount must be lower or equal to limit"); + + address[] memory addRecipientToAllowedListRoleHolders = new address[]( + _grantRightsToEVMScriptExecutor ? 3 : 2 + ); + addRecipientToAllowedListRoleHolders[0] = admin; + addRecipientToAllowedListRoleHolders[1] = address(this); + if (_grantRightsToEVMScriptExecutor) { + addRecipientToAllowedListRoleHolders[2] = evmScriptExecutor; + } + address[] memory removeRecipientFromAllowedListRoleHolders = new address[]( + _grantRightsToEVMScriptExecutor ? 2 : 1 + ); + removeRecipientFromAllowedListRoleHolders[0] = admin; + if (_grantRightsToEVMScriptExecutor) { + removeRecipientFromAllowedListRoleHolders[1] = evmScriptExecutor; + } + address[] memory setLimitParametersRoleHolders = new address[](2); + setLimitParametersRoleHolders[0] = admin; + setLimitParametersRoleHolders[1] = address(this); + address[] memory updateSpentAmountRoleHolders = new address[](3); + updateSpentAmountRoleHolders[0] = admin; + updateSpentAmountRoleHolders[1] = evmScriptExecutor; + updateSpentAmountRoleHolders[2] = address(this); + + registry = factory.deployAllowedRecipientsRegistry( + admin, + addRecipientToAllowedListRoleHolders, + removeRecipientFromAllowedListRoleHolders, + setLimitParametersRoleHolders, + updateSpentAmountRoleHolders, + bokkyPooBahsDateTimeContract + ); + + assert(registry.bokkyPooBahsDateTimeContract() == bokkyPooBahsDateTimeContract); + + for (uint256 i = 0; i < _recipients.length; i++) { + registry.addRecipient(_recipients[i], _titles[i]); + } + registry.renounceRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, address(this)); + + assert(registry.getAllowedRecipients().length == _recipients.length); + + for (uint256 i = 0; i < _recipients.length; i++) { + assert(registry.isRecipientAllowed(_recipients[i])); + } + + registry.setLimitParameters(_limit, _periodDurationMonths); + registry.renounceRole(SET_PARAMETERS_ROLE, address(this)); + + (uint256 registryLimit, uint256 registryPeriodDuration) = registry.getLimitParameters(); + assert(registryLimit == _limit); + assert(registryPeriodDuration == _periodDurationMonths); + + registry.updateSpentAmount(_spentAmount); + registry.renounceRole(UPDATE_SPENT_AMOUNT_ROLE, address(this)); + + assert(registry.spendableBalance() == _limit - _spentAmount); + + assert(registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, admin)); + assert(registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, admin)); + assert(registry.hasRole(SET_PARAMETERS_ROLE, admin)); + assert(registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, admin)); + assert(registry.hasRole(DEFAULT_ADMIN_ROLE, admin)); + + if (_grantRightsToEVMScriptExecutor) { + assert(registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, evmScriptExecutor)); + assert(registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, evmScriptExecutor)); + } else { + assert(!registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, evmScriptExecutor)); + assert(!registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, evmScriptExecutor)); + } + assert(registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, evmScriptExecutor)); + assert(!registry.hasRole(SET_PARAMETERS_ROLE, evmScriptExecutor)); + assert(!registry.hasRole(DEFAULT_ADMIN_ROLE, evmScriptExecutor)); + + assert(!registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, address(this))); + assert(!registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, address(this))); + assert(!registry.hasRole(SET_PARAMETERS_ROLE, address(this))); + assert(!registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, address(this))); + assert(!registry.hasRole(DEFAULT_ADMIN_ROLE, address(this))); + } + + function deployTopUpAllowedRecipients( + address _trustedCaller, + address _allowedRecipientsRegistry, + address _token + ) public returns (ITopUpAllowedRecipients topUpAllowedRecipients) { + topUpAllowedRecipients = factory.deployTopUpAllowedRecipients( + _trustedCaller, + _allowedRecipientsRegistry, + _token, + finance, + easyTrack + ); + + assert(topUpAllowedRecipients.token() == _token); + assert(topUpAllowedRecipients.finance() == finance); + assert(topUpAllowedRecipients.easyTrack() == easyTrack); + assert(topUpAllowedRecipients.trustedCaller() == _trustedCaller); + assert( + address(topUpAllowedRecipients.allowedRecipientsRegistry()) == + _allowedRecipientsRegistry + ); + } + + function deployAddAllowedRecipient(address _trustedCaller, address _allowedRecipientsRegistry) + public + returns (IAddAllowedRecipient addAllowedRecipient) + { + addAllowedRecipient = factory.deployAddAllowedRecipient( + _trustedCaller, + _allowedRecipientsRegistry + ); + + assert(addAllowedRecipient.trustedCaller() == _trustedCaller); + assert( + address(addAllowedRecipient.allowedRecipientsRegistry()) == _allowedRecipientsRegistry + ); + } + + function deployRemoveAllowedRecipient( + address _trustedCaller, + address _allowedRecipientsRegistry + ) public returns (IRemoveAllowedRecipient removeAllowedRecipient) { + removeAllowedRecipient = factory.deployRemoveAllowedRecipient( + _trustedCaller, + _allowedRecipientsRegistry + ); + + assert(removeAllowedRecipient.trustedCaller() == _trustedCaller); + assert( + address(removeAllowedRecipient.allowedRecipientsRegistry()) == + _allowedRecipientsRegistry + ); + } + + function deployFullSetup( + address _trustedCaller, + address _token, + uint256 _limit, + uint256 _periodDurationMonths, + address[] memory _recipients, + string[] memory _titles, + uint256 _spentAmount + ) + public + returns ( + IAllowedRecipientsRegistry allowedRecipientsRegistry, + ITopUpAllowedRecipients topUpAllowedRecipients, + IAddAllowedRecipient addAllowedRecipient, + IRemoveAllowedRecipient removeAllowedRecipient + ) + { + allowedRecipientsRegistry = deployAllowedRecipientsRegistry( + _limit, + _periodDurationMonths, + _recipients, + _titles, + _spentAmount, + true + ); + + topUpAllowedRecipients = deployTopUpAllowedRecipients( + _trustedCaller, + address(allowedRecipientsRegistry), + _token + ); + + addAllowedRecipient = deployAddAllowedRecipient( + _trustedCaller, + address(allowedRecipientsRegistry) + ); + + removeAllowedRecipient = deployRemoveAllowedRecipient( + _trustedCaller, + address(allowedRecipientsRegistry) + ); + } + + function deploySingleRecipientTopUpOnlySetup( + address _recipient, + string memory _title, + address _token, + uint256 _limit, + uint256 _periodDurationMonths, + uint256 _spentAmount + ) + public + returns ( + IAllowedRecipientsRegistry allowedRecipientsRegistry, + ITopUpAllowedRecipients topUpAllowedRecipients + ) + { + address[] memory recipients = new address[](1); + recipients[0] = _recipient; + + string[] memory titles = new string[](1); + titles[0] = _title; + + allowedRecipientsRegistry = deployAllowedRecipientsRegistry( + _limit, + _periodDurationMonths, + recipients, + titles, + _spentAmount, + false + ); + + topUpAllowedRecipients = deployTopUpAllowedRecipients( + _recipient, + address(allowedRecipientsRegistry), + _token + ); + } +} diff --git a/contracts/AllowedRecipientsFactory.sol b/contracts/AllowedRecipientsFactory.sol new file mode 100644 index 00000000..123798a5 --- /dev/null +++ b/contracts/AllowedRecipientsFactory.sol @@ -0,0 +1,136 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +import "./EVMScriptFactories/AddAllowedRecipient.sol"; +import "./EVMScriptFactories/RemoveAllowedRecipient.sol"; +import "./EVMScriptFactories/TopUpAllowedRecipients.sol"; +import "./AllowedRecipientsRegistry.sol"; + +/// @author bulbozaur +/// @notice Factory for Allowed Recipient Easy Track contracts +contract AllowedRecipientsFactory { + event AllowedRecipientsRegistryDeployed( + address indexed creator, + address indexed allowedRecipientsRegistry, + address _defaultAdmin, + address[] addRecipientToAllowedListRoleHolders, + address[] removeRecipientFromAllowedListRoleHolders, + address[] setLimitParametersRoleHolders, + address[] updateSpentAmountRoleHolders, + IBokkyPooBahsDateTimeContract bokkyPooBahsDateTimeContract + ); + + event TopUpAllowedRecipientsDeployed( + address indexed creator, + address indexed topUpAllowedRecipients, + address trustedCaller, + address allowedRecipientsRegistry, + address finance, + address token, + address easyTrack + ); + + event AddAllowedRecipientDeployed( + address indexed creator, + address indexed addAllowedRecipient, + address trustedCaller, + address allowedRecipientsRegistry + ); + + event RemoveAllowedRecipientDeployed( + address indexed creator, + address indexed removeAllowedRecipient, + address trustedCaller, + address allowedRecipientsRegistry + ); + + function deployAllowedRecipientsRegistry( + address _defaultAdmin, + address[] memory _addRecipientToAllowedListRoleHolders, + address[] memory _removeRecipientFromAllowedListRoleHolders, + address[] memory _setLimitParametersRoleHolders, + address[] memory _updateSpentAmountRoleHolders, + IBokkyPooBahsDateTimeContract _bokkyPooBahsDateTimeContract + ) public returns (AllowedRecipientsRegistry registry) { + registry = new AllowedRecipientsRegistry( + _defaultAdmin, + _addRecipientToAllowedListRoleHolders, + _removeRecipientFromAllowedListRoleHolders, + _setLimitParametersRoleHolders, + _updateSpentAmountRoleHolders, + _bokkyPooBahsDateTimeContract + ); + + emit AllowedRecipientsRegistryDeployed( + msg.sender, + address(registry), + _defaultAdmin, + _addRecipientToAllowedListRoleHolders, + _removeRecipientFromAllowedListRoleHolders, + _setLimitParametersRoleHolders, + _updateSpentAmountRoleHolders, + _bokkyPooBahsDateTimeContract + ); + } + + function deployTopUpAllowedRecipients( + address _trustedCaller, + address _allowedRecipientsRegistry, + address _token, + address _finance, + address _easyTrack + ) public returns (TopUpAllowedRecipients topUpAllowedRecipients) { + topUpAllowedRecipients = new TopUpAllowedRecipients( + _trustedCaller, + _allowedRecipientsRegistry, + _finance, + _token, + _easyTrack + ); + + emit TopUpAllowedRecipientsDeployed( + msg.sender, + address(topUpAllowedRecipients), + _trustedCaller, + _allowedRecipientsRegistry, + _finance, + _token, + _easyTrack + ); + + return topUpAllowedRecipients; + } + + function deployAddAllowedRecipient(address _trustedCaller, address _allowedRecipientsRegistry) + public + returns (AddAllowedRecipient addAllowedRecipient) + { + addAllowedRecipient = new AddAllowedRecipient(_trustedCaller, _allowedRecipientsRegistry); + + emit AddAllowedRecipientDeployed( + msg.sender, + address(addAllowedRecipient), + _trustedCaller, + _allowedRecipientsRegistry + ); + } + + function deployRemoveAllowedRecipient( + address _trustedCaller, + address _allowedRecipientsRegistry + ) public returns (RemoveAllowedRecipient removeAllowedRecipient) { + removeAllowedRecipient = new RemoveAllowedRecipient( + _trustedCaller, + _allowedRecipientsRegistry + ); + + emit RemoveAllowedRecipientDeployed( + msg.sender, + address(removeAllowedRecipient), + _trustedCaller, + _allowedRecipientsRegistry + ); + } +} diff --git a/contracts/AllowedRecipientsRegistry.sol b/contracts/AllowedRecipientsRegistry.sol new file mode 100644 index 00000000..28dfe58a --- /dev/null +++ b/contracts/AllowedRecipientsRegistry.sol @@ -0,0 +1,148 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +import "./LimitsChecker.sol"; + +/// @author psirex, zuzueeka +/// @title Registry of allowed addresses for payouts +/// @notice Stores list of allowed addresses +contract AllowedRecipientsRegistry is LimitsChecker { + // ------------- + // EVENTS + // ------------- + event RecipientAdded(address indexed _recipient, string _title); + event RecipientRemoved(address indexed _recipient); + + // ------------- + // ROLES + // ------------- + bytes32 public constant ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE = + keccak256("ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE"); + bytes32 public constant REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE = + keccak256("REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE"); + + // ------------- + // ERRORS + // ------------- + string private constant ERROR_RECIPIENT_ALREADY_ADDED_TO_ALLOWED_LIST = + "RECIPIENT_ALREADY_ADDED_TO_ALLOWED_LIST"; + string private constant ERROR_RECIPIENT_NOT_FOUND_IN_ALLOWED_LIST = + "RECIPIENT_NOT_FOUND_IN_ALLOWED_LIST"; + + // ------------- + // VARIABLES + // ------------- + + /// @dev List of allowed addresses for payouts + address[] public allowedRecipients; + + // Position of the address in the `allowedRecipients` array, + // plus 1 because index 0 means a value is not in the set. + mapping(address => uint256) private allowedRecipientIndices; + + // ------------- + // CONSTRUCTOR + // ------------- + + /// @param _admin Address which will be granted with role DEFAULT_ADMIN_ROLE + /// @param _addRecipientToAllowedListRoleHolders List of addresses which will be + /// granted with role ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE + /// @param _removeRecipientFromAllowedListRoleHolders List of addresses which will + /// be granted with role REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE + /// @param _setParametersRoleHolders List of addresses which will + /// be granted with role SET_PARAMETERS_ROLE + /// @param _updateSpentAmountRoleHolders List of addresses which will + /// be granted with role UPDATE_SPENT_AMOUNT_ROLE + /// @param _bokkyPooBahsDateTimeContract Address of bokkyPooBahs DateTime Contract + constructor( + address _admin, + address[] memory _addRecipientToAllowedListRoleHolders, + address[] memory _removeRecipientFromAllowedListRoleHolders, + address[] memory _setParametersRoleHolders, + address[] memory _updateSpentAmountRoleHolders, + IBokkyPooBahsDateTimeContract _bokkyPooBahsDateTimeContract + ) + LimitsChecker( + _setParametersRoleHolders, + _updateSpentAmountRoleHolders, + _bokkyPooBahsDateTimeContract + ) + { + _setupRole(DEFAULT_ADMIN_ROLE, _admin); + for (uint256 i = 0; i < _addRecipientToAllowedListRoleHolders.length; i++) { + _setupRole( + ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, + _addRecipientToAllowedListRoleHolders[i] + ); + } + for (uint256 i = 0; i < _removeRecipientFromAllowedListRoleHolders.length; i++) { + _setupRole( + REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, + _removeRecipientFromAllowedListRoleHolders[i] + ); + } + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Adds address to list of allowed addresses for payouts + function addRecipient(address _recipient, string memory _title) + external + onlyRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE) + { + require( + allowedRecipientIndices[_recipient] == 0, + ERROR_RECIPIENT_ALREADY_ADDED_TO_ALLOWED_LIST + ); + + allowedRecipients.push(_recipient); + allowedRecipientIndices[_recipient] = allowedRecipients.length; + emit RecipientAdded(_recipient, _title); + } + + /// @notice Removes address from list of allowed addresses for payouts + /// @dev To delete an allowed address from the allowedRecipients array in O(1), + /// we swap the element to delete with the last one in the array, + /// and then remove the last element (sometimes called as 'swap and pop'). + function removeRecipient(address _recipient) + external + onlyRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE) + { + uint256 index = _getAllowedRecipientIndex(_recipient); + uint256 lastIndex = allowedRecipients.length - 1; + + if (index != lastIndex) { + address lastAllowedRecipient = allowedRecipients[lastIndex]; + allowedRecipients[index] = lastAllowedRecipient; + allowedRecipientIndices[lastAllowedRecipient] = index + 1; + } + + allowedRecipients.pop(); + delete allowedRecipientIndices[_recipient]; + emit RecipientRemoved(_recipient); + } + + /// @notice Returns if passed address is listed as allowed recipient in the registry + function isRecipientAllowed(address _recipient) external view returns (bool) { + return allowedRecipientIndices[_recipient] > 0; + } + + /// @notice Returns current list of allowed recipients + function getAllowedRecipients() external view returns (address[] memory) { + return allowedRecipients; + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _getAllowedRecipientIndex(address _recipient) private view returns (uint256 _index) { + _index = allowedRecipientIndices[_recipient]; + require(_index > 0, ERROR_RECIPIENT_NOT_FOUND_IN_ALLOWED_LIST); + _index -= 1; + } +} diff --git a/contracts/EVMScriptFactories/ActivateNodeOperators.sol b/contracts/EVMScriptFactories/ActivateNodeOperators.sol new file mode 100644 index 00000000..ada02984 --- /dev/null +++ b/contracts/EVMScriptFactories/ActivateNodeOperators.sol @@ -0,0 +1,175 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; +import "../interfaces/IACL.sol"; + +/// @notice Creates EVMScript to activate several node operators +contract ActivateNodeOperators is TrustedCaller, IEVMScriptFactory { + struct ActivateNodeOperatorInput { + uint256 nodeOperatorId; + address managerAddress; + } + + // ------------- + // CONSTANTS + // ------------- + + bytes4 private constant ACTIVATE_NODE_OPERATOR_SELECTOR = + bytes4(keccak256("activateNodeOperator(uint256)")); + bytes4 private constant GRANT_PERMISSION_P_SELECTOR = + bytes4(keccak256("grantPermissionP(address,address,bytes32,uint256[])")); + bytes32 private constant MANAGE_SIGNING_KEYS_ROLE = keccak256("MANAGE_SIGNING_KEYS"); + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + /// @notice Address of Aragon ACL contract + IACL public immutable acl; + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_WRONG_OPERATOR_ACTIVE_STATE = "WRONG_OPERATOR_ACTIVE_STATE"; + string private constant ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE = + "NODE_OPERATOR_INDEX_OUT_OF_RANGE"; + string private constant ERROR_MANAGER_ALREADY_HAS_ROLE = "MANAGER_ALREADY_HAS_ROLE"; + string private constant ERROR_NODE_OPERATORS_IS_NOT_SORTED = "NODE_OPERATORS_IS_NOT_SORTED"; + string private constant ERROR_ZERO_MANAGER_ADDRESS = "ZERO_MANAGER_ADDRESS"; + string private constant ERROR_MANAGER_ADDRESSES_HAS_DUPLICATE = + "MANAGER_ADDRESSES_HAS_DUPLICATE"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry, + address _acl + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + acl = IACL(_acl); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to activate batch of node operators + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (ActivateNodeOperatorInput[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + ActivateNodeOperatorInput[] memory decodedCallData = _decodeEVMScriptCallData( + _evmScriptCallData + ); + + _validateInputData(decodedCallData); + + address[] memory toAddresses = new address[](decodedCallData.length * 2); + bytes4[] memory methodIds = new bytes4[](decodedCallData.length * 2); + bytes[] memory encodedCalldata = new bytes[](decodedCallData.length * 2); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + toAddresses[i * 2] = address(nodeOperatorsRegistry); + methodIds[i * 2] = ACTIVATE_NODE_OPERATOR_SELECTOR; + encodedCalldata[i * 2] = abi.encode(decodedCallData[i].nodeOperatorId); + + // See https://legacy-docs.aragon.org/developers/tools/aragonos/reference-aragonos-3#parameter-interpretation for details + uint256[] memory permissionParams = new uint256[](1); + permissionParams[0] = (1 << 240) + decodedCallData[i].nodeOperatorId; + + toAddresses[i * 2 + 1] = address(acl); + methodIds[i * 2 + 1] = GRANT_PERMISSION_P_SELECTOR; + encodedCalldata[i * 2 + 1] = abi.encode( + decodedCallData[i].managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE, + permissionParams + ); + } + + return EVMScriptCreator.createEVMScript(toAddresses, methodIds, encodedCalldata); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (ActivateNodeOperatorInput[]) + /// @return ActivateNodeOperatorInput[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (ActivateNodeOperatorInput[] memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (ActivateNodeOperatorInput[] memory) { + return abi.decode(_evmScriptCallData, (ActivateNodeOperatorInput[])); + } + + function _validateInputData(ActivateNodeOperatorInput[] memory _decodedCallData) private view { + uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); + require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); + require( + _decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, + ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE + ); + + for (uint256 i = 0; i < _decodedCallData.length; ++i) { + require( + i == 0 || + _decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, + ERROR_NODE_OPERATORS_IS_NOT_SORTED + ); + require( + nodeOperatorsRegistry.getNodeOperatorIsActive(_decodedCallData[i].nodeOperatorId) == + false, + ERROR_WRONG_OPERATOR_ACTIVE_STATE + ); + + require(_decodedCallData[i].managerAddress != address(0), ERROR_ZERO_MANAGER_ADDRESS); + + address managerAddress = _decodedCallData[i].managerAddress; + for (uint256 testIndex = i + 1; testIndex < _decodedCallData.length; ++testIndex) { + require( + managerAddress != _decodedCallData[testIndex].managerAddress, + ERROR_MANAGER_ADDRESSES_HAS_DUPLICATE + ); + } + + require( + acl.hasPermission( + _decodedCallData[i].managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == false, + ERROR_MANAGER_ALREADY_HAS_ROLE + ); + require( + acl.getPermissionParamsLength( + _decodedCallData[i].managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == 0, + ERROR_MANAGER_ALREADY_HAS_ROLE + ); + } + } +} diff --git a/contracts/EVMScriptFactories/AddAllowedRecipient.sol b/contracts/EVMScriptFactories/AddAllowedRecipient.sol new file mode 100644 index 00000000..1c9b376b --- /dev/null +++ b/contracts/EVMScriptFactories/AddAllowedRecipient.sol @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +import "../TrustedCaller.sol"; +import "../AllowedRecipientsRegistry.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; + +/// @author psirex, zuzueeka +/// @notice Creates EVMScript to add new allowed recipient address to AllowedRecipientsRegistry +contract AddAllowedRecipient is TrustedCaller, IEVMScriptFactory { + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_RECIPIENT_ADDRESS_IS_ZERO_ADDRESS = + "RECIPIENT_ADDRESS_IS_ZERO_ADDRESS"; + string private constant ERROR_ALLOWED_RECIPIENT_ALREADY_ADDED = + "ALLOWED_RECIPIENT_ALREADY_ADDED"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of AllowedRecipientsRegistry + AllowedRecipientsRegistry public allowedRecipientsRegistry; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor(address _trustedCaller, address _allowedRecipientsRegistry) + TrustedCaller(_trustedCaller) + { + allowedRecipientsRegistry = AllowedRecipientsRegistry(_allowedRecipientsRegistry); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to add new allowed recipient address to allowedRecipientsRegistry + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded tuple: (address recipientAddress, string memory title) + function createEVMScript(address _creator, bytes memory _evmScriptCallData) + external + view + override + onlyTrustedCaller(_creator) + returns (bytes memory) + { + (address recipientAddress, ) = _decodeEVMScriptCallData(_evmScriptCallData); + require(recipientAddress != address(0), ERROR_RECIPIENT_ADDRESS_IS_ZERO_ADDRESS); + require( + !allowedRecipientsRegistry.isRecipientAllowed(recipientAddress), + ERROR_ALLOWED_RECIPIENT_ALREADY_ADDED + ); + + return + EVMScriptCreator.createEVMScript( + address(allowedRecipientsRegistry), + allowedRecipientsRegistry.addRecipient.selector, + _evmScriptCallData + ); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded tuple: (address recipientAddress, string title) + /// @return Address of recipient to add + /// @return Title of the recipient + function decodeEVMScriptCallData(bytes memory _evmScriptCallData) + external + pure + returns (address, string memory) + { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData(bytes memory _evmScriptCallData) + private + pure + returns (address, string memory) + { + return abi.decode(_evmScriptCallData, (address, string)); + } +} diff --git a/contracts/EVMScriptFactories/AddNodeOperators.sol b/contracts/EVMScriptFactories/AddNodeOperators.sol new file mode 100644 index 00000000..2537225f --- /dev/null +++ b/contracts/EVMScriptFactories/AddNodeOperators.sol @@ -0,0 +1,206 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; +import "../interfaces/IACL.sol"; + +/// @notice Creates EVMScript to add new batch of node operators +contract AddNodeOperators is TrustedCaller, IEVMScriptFactory { + struct AddNodeOperatorInput { + string name; + address rewardAddress; + address managerAddress; + } + + // ------------- + // CONSTANTS + // ------------- + + bytes4 private constant ADD_NODE_OPERATOR_SELECTOR = + bytes4(keccak256("addNodeOperator(string,address)")); + bytes4 private constant GRANT_PERMISSION_P_SELECTOR = + bytes4(keccak256("grantPermissionP(address,address,bytes32,uint256[])")); + bytes32 private constant MANAGE_SIGNING_KEYS_ROLE = keccak256("MANAGE_SIGNING_KEYS"); + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + /// @notice Address of Aragon ACL contract + IACL public immutable acl; + /// @notice Address of Lido contract + address public immutable lido; + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_MANAGER_ALREADY_HAS_ROLE = "MANAGER_ALREADY_HAS_ROLE"; + string private constant ERROR_MANAGER_ADDRESSES_HAS_DUPLICATE = + "MANAGER_ADDRESSES_HAS_DUPLICATE"; + string private constant ERROR_NODE_OPERATORS_COUNT_MISMATCH = "NODE_OPERATORS_COUNT_MISMATCH"; + string private constant ERROR_LIDO_REWARD_ADDRESS = "LIDO_REWARD_ADDRESS"; + string private constant ERROR_ZERO_REWARD_ADDRESS = "ZERO_REWARD_ADDRESS"; + string private constant ERROR_ZERO_MANAGER_ADDRESS = "ZERO_MANAGER_ADDRESS"; + string private constant ERROR_WRONG_NAME_LENGTH = "WRONG_NAME_LENGTH"; + string private constant ERROR_MAX_OPERATORS_COUNT_EXCEEDED = "MAX_OPERATORS_COUNT_EXCEEDED"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry, + address _acl, + address _lido + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + acl = IACL(_acl); + lido = _lido; + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to add batch of node operators + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (uint256,AddNodeOperatorInput[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + ( + uint256 nodeOperatorsCount, + AddNodeOperatorInput[] memory decodedCallData + ) = _decodeEVMScriptCallData(_evmScriptCallData); + + address[] memory toAddresses = new address[](decodedCallData.length * 2); + bytes4[] memory methodIds = new bytes4[](decodedCallData.length * 2); + bytes[] memory encodedCalldata = new bytes[](decodedCallData.length * 2); + + _validateInputData(nodeOperatorsCount, decodedCallData); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + toAddresses[i * 2] = address(nodeOperatorsRegistry); + methodIds[i * 2] = ADD_NODE_OPERATOR_SELECTOR; + encodedCalldata[i * 2] = abi.encode( + decodedCallData[i].name, + decodedCallData[i].rewardAddress + ); + + // See https://legacy-docs.aragon.org/developers/tools/aragonos/reference-aragonos-3#parameter-interpretation for details + uint256[] memory permissionParams = new uint256[](1); + permissionParams[0] = (1 << 240) + nodeOperatorsCount + i; + + toAddresses[i * 2 + 1] = address(acl); + methodIds[i * 2 + 1] = GRANT_PERMISSION_P_SELECTOR; + encodedCalldata[i * 2 + 1] = abi.encode( + decodedCallData[i].managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE, + permissionParams + ); + } + + return EVMScriptCreator.createEVMScript(toAddresses, methodIds, encodedCalldata); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (uint256, AddNodeOperatorInput[]) + /// @return nodeOperatorsCount current number of node operators in registry + /// @return nodeOperators AddNodeOperatorInput[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) + external + pure + returns (uint256 nodeOperatorsCount, AddNodeOperatorInput[] memory nodeOperators) + { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) + private + pure + returns (uint256 nodeOperatorsCount, AddNodeOperatorInput[] memory nodeOperators) + { + (nodeOperatorsCount, nodeOperators) = abi.decode( + _evmScriptCallData, + (uint256, AddNodeOperatorInput[]) + ); + } + + function _validateInputData( + uint256 _nodeOperatorsCount, + AddNodeOperatorInput[] memory _nodeOperatorInputs + ) private view { + uint256 maxNameLength = nodeOperatorsRegistry.MAX_NODE_OPERATOR_NAME_LENGTH(); + uint256 calldataLength = _nodeOperatorInputs.length; + + require(calldataLength > 0, ERROR_EMPTY_CALLDATA); + + require( + nodeOperatorsRegistry.getNodeOperatorsCount() == _nodeOperatorsCount, + ERROR_NODE_OPERATORS_COUNT_MISMATCH + ); + + require( + _nodeOperatorsCount + calldataLength <= nodeOperatorsRegistry.MAX_NODE_OPERATORS_COUNT(), + ERROR_MAX_OPERATORS_COUNT_EXCEEDED + ); + + for (uint256 i = 0; i < calldataLength; ++i) { + address managerAddress = _nodeOperatorInputs[i].managerAddress; + address rewardAddress = _nodeOperatorInputs[i].rewardAddress; + string memory name = _nodeOperatorInputs[i].name; + for (uint256 testIndex = i + 1; testIndex < calldataLength; ++testIndex) { + require( + managerAddress != _nodeOperatorInputs[testIndex].managerAddress, + ERROR_MANAGER_ADDRESSES_HAS_DUPLICATE + ); + } + + require( + acl.hasPermission( + managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == false, + ERROR_MANAGER_ALREADY_HAS_ROLE + ); + require( + acl.getPermissionParamsLength( + managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == 0, + ERROR_MANAGER_ALREADY_HAS_ROLE + ); + + require(rewardAddress != lido, ERROR_LIDO_REWARD_ADDRESS); + require(rewardAddress != address(0), ERROR_ZERO_REWARD_ADDRESS); + require(managerAddress != address(0), ERROR_ZERO_MANAGER_ADDRESS); + + require( + bytes(name).length > 0 && bytes(name).length <= maxNameLength, + ERROR_WRONG_NAME_LENGTH + ); + } + } +} diff --git a/contracts/EVMScriptFactories/ChangeNodeOperatorManagers.sol b/contracts/EVMScriptFactories/ChangeNodeOperatorManagers.sol new file mode 100644 index 00000000..9a520196 --- /dev/null +++ b/contracts/EVMScriptFactories/ChangeNodeOperatorManagers.sol @@ -0,0 +1,196 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; +import "../interfaces/IACL.sol"; + +/// @notice Creates EVMScript to change signing keys manager for several node operators +contract ChangeNodeOperatorManagers is TrustedCaller, IEVMScriptFactory { + struct ChangeNodeOperatorManagersInput { + uint256 nodeOperatorId; + address oldManagerAddress; + address newManagerAddress; + } + + // ------------- + // CONSTANTS + // ------------- + + bytes32 private constant MANAGE_SIGNING_KEYS_ROLE = keccak256("MANAGE_SIGNING_KEYS"); + bytes4 private constant GRANT_PERMISSION_P_SELECTOR = + bytes4(keccak256("grantPermissionP(address,address,bytes32,uint256[])")); + bytes4 private constant REVOKE_PERMISSION_SELECTOR = + bytes4(keccak256("revokePermission(address,address,bytes32)")); + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE = + "NODE_OPERATOR_INDEX_OUT_OF_RANGE"; + string private constant ERROR_OLD_MANAGER_HAS_NO_ROLE = "OLD_MANAGER_HAS_NO_ROLE"; + string private constant ERROR_MANAGER_ALREADY_HAS_ROLE = "MANAGER_ALREADY_HAS_ROLE"; + string private constant ERROR_MANAGER_ADDRESSES_HAS_DUPLICATE = + "MANAGER_ADDRESSES_HAS_DUPLICATE"; + string private constant ERROR_NODE_OPERATORS_IS_NOT_SORTED = "NODE_OPERATORS_IS_NOT_SORTED"; + string private constant ERROR_ZERO_MANAGER_ADDRESS = "ZERO_MANAGER_ADDRESS"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + /// @notice Address of Aragon ACL contract + IACL public immutable acl; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry, + address _acl + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + acl = IACL(_acl); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to change managers of several node operators + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (ChangeNodeOperatorManagersInput[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + ChangeNodeOperatorManagersInput[] memory decodedCallData = _decodeEVMScriptCallData( + _evmScriptCallData + ); + + bytes4[] memory methodIds = new bytes4[](decodedCallData.length * 2); + bytes[] memory encodedCalldata = new bytes[](decodedCallData.length * 2); + + _validateInputData(decodedCallData); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + methodIds[i * 2] = REVOKE_PERMISSION_SELECTOR; + encodedCalldata[i * 2] = abi.encode( + decodedCallData[i].oldManagerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ); + + // See https://legacy-docs.aragon.org/developers/tools/aragonos/reference-aragonos-3#parameter-interpretation for details + uint256[] memory permissionParams = new uint256[](1); + permissionParams[0] = (1 << 240) + decodedCallData[i].nodeOperatorId; + methodIds[i * 2 + 1] = GRANT_PERMISSION_P_SELECTOR; + encodedCalldata[i * 2 + 1] = abi.encode( + decodedCallData[i].newManagerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE, + permissionParams + ); + } + + return EVMScriptCreator.createEVMScript(address(acl), methodIds, encodedCalldata); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (ChangeNodeOperatorManagersInput[]) + /// @return ChangeNodeOperatorManagersInput[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (ChangeNodeOperatorManagersInput[] memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (ChangeNodeOperatorManagersInput[] memory) { + return abi.decode(_evmScriptCallData, (ChangeNodeOperatorManagersInput[])); + } + + function _validateInputData( + ChangeNodeOperatorManagersInput[] memory _decodedCallData + ) private view { + uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); + require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); + require( + _decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, + ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE + ); + + for (uint256 i = 0; i < _decodedCallData.length; ++i) { + require( + i == 0 || + _decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, + ERROR_NODE_OPERATORS_IS_NOT_SORTED + ); + + address managerAddress = _decodedCallData[i].newManagerAddress; + for (uint256 testIndex = i + 1; testIndex < _decodedCallData.length; ++testIndex) { + require( + managerAddress != _decodedCallData[testIndex].newManagerAddress, + ERROR_MANAGER_ADDRESSES_HAS_DUPLICATE + ); + } + require( + acl.getPermissionParamsLength( + _decodedCallData[i].oldManagerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == 1, + ERROR_OLD_MANAGER_HAS_NO_ROLE + ); + + // See https://legacy-docs.aragon.org/developers/tools/aragonos/reference-aragonos-3#parameter-interpretation for details + (uint8 paramIndex, uint8 paramOp, uint240 param) = acl.getPermissionParam( + _decodedCallData[i].oldManagerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE, + 0 + ); + + require(paramIndex == 0, ERROR_OLD_MANAGER_HAS_NO_ROLE); + require(paramOp == 1, ERROR_OLD_MANAGER_HAS_NO_ROLE); + require(param == _decodedCallData[i].nodeOperatorId, ERROR_OLD_MANAGER_HAS_NO_ROLE); + + require( + _decodedCallData[i].newManagerAddress != address(0), + ERROR_ZERO_MANAGER_ADDRESS + ); + + require( + acl.hasPermission( + _decodedCallData[i].newManagerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == false, + ERROR_MANAGER_ALREADY_HAS_ROLE + ); + require( + acl.getPermissionParamsLength( + _decodedCallData[i].newManagerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == 0, + ERROR_MANAGER_ALREADY_HAS_ROLE + ); + } + } +} diff --git a/contracts/EVMScriptFactories/DeactivateNodeOperators.sol b/contracts/EVMScriptFactories/DeactivateNodeOperators.sol new file mode 100644 index 00000000..01cbfc2d --- /dev/null +++ b/contracts/EVMScriptFactories/DeactivateNodeOperators.sol @@ -0,0 +1,163 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; +import "../interfaces/IACL.sol"; + +/// @notice Creates EVMScript to deactivate several node operators +contract DeactivateNodeOperators is TrustedCaller, IEVMScriptFactory { + struct DeactivateNodeOperatorInput { + uint256 nodeOperatorId; + address managerAddress; + } + + // ------------- + // CONSTANTS + // ------------- + + bytes4 private constant DEACTIVATE_NODE_OPERATOR_SELECTOR = + bytes4(keccak256("deactivateNodeOperator(uint256)")); + bytes4 private constant REVOKE_PERMISSION_SELECTOR = + bytes4(keccak256("revokePermission(address,address,bytes32)")); + bytes32 private constant MANAGE_SIGNING_KEYS_ROLE = keccak256("MANAGE_SIGNING_KEYS"); + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + /// @notice Address of Aragon ACL contract + IACL public immutable acl; + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_WRONG_OPERATOR_ACTIVE_STATE = "WRONG_OPERATOR_ACTIVE_STATE"; + string private constant ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE = + "NODE_OPERATOR_INDEX_OUT_OF_RANGE"; + string private constant ERROR_MANAGER_HAS_NO_ROLE = "MANAGER_HAS_NO_ROLE"; + string private constant ERROR_NODE_OPERATORS_IS_NOT_SORTED = "NODE_OPERATORS_IS_NOT_SORTED"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry, + address _acl + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + acl = IACL(_acl); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to deactivate batch of node operators + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (DeactivateNodeOperatorInput[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + DeactivateNodeOperatorInput[] memory decodedCallData = _decodeEVMScriptCallData( + _evmScriptCallData + ); + + _validateInputData(decodedCallData); + + address[] memory toAddresses = new address[](decodedCallData.length * 2); + bytes4[] memory methodIds = new bytes4[](decodedCallData.length * 2); + bytes[] memory encodedCalldata = new bytes[](decodedCallData.length * 2); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + toAddresses[i * 2] = address(nodeOperatorsRegistry); + methodIds[i * 2] = DEACTIVATE_NODE_OPERATOR_SELECTOR; + encodedCalldata[i * 2] = abi.encode(decodedCallData[i].nodeOperatorId); + + toAddresses[i * 2 + 1] = address(acl); + methodIds[i * 2 + 1] = REVOKE_PERMISSION_SELECTOR; + encodedCalldata[i * 2 + 1] = abi.encode( + decodedCallData[i].managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ); + } + + return EVMScriptCreator.createEVMScript(toAddresses, methodIds, encodedCalldata); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (DeactivateNodeOperatorInput[]) + /// @return DeactivateNodeOperatorInput[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (DeactivateNodeOperatorInput[] memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (DeactivateNodeOperatorInput[] memory) { + return abi.decode(_evmScriptCallData, (DeactivateNodeOperatorInput[])); + } + + function _validateInputData( + DeactivateNodeOperatorInput[] memory _decodedCallData + ) private view { + uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); + require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); + require( + _decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, + ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE + ); + + for (uint256 i = 0; i < _decodedCallData.length; ++i) { + require( + i == 0 || + _decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, + ERROR_NODE_OPERATORS_IS_NOT_SORTED + ); + require( + nodeOperatorsRegistry.getNodeOperatorIsActive(_decodedCallData[i].nodeOperatorId) == + true, + ERROR_WRONG_OPERATOR_ACTIVE_STATE + ); + + require( + acl.getPermissionParamsLength( + _decodedCallData[i].managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE + ) == 1, + ERROR_MANAGER_HAS_NO_ROLE + ); + + // See https://legacy-docs.aragon.org/developers/tools/aragonos/reference-aragonos-3#parameter-interpretation for details + (uint8 paramIndex, uint8 paramOp, uint240 param) = acl.getPermissionParam( + _decodedCallData[i].managerAddress, + address(nodeOperatorsRegistry), + MANAGE_SIGNING_KEYS_ROLE, + 0 + ); + + require(paramIndex == 0, ERROR_MANAGER_HAS_NO_ROLE); + require(paramOp == 1, ERROR_MANAGER_HAS_NO_ROLE); + require(param == _decodedCallData[i].nodeOperatorId, ERROR_MANAGER_HAS_NO_ROLE); + } + } +} diff --git a/contracts/EVMScriptFactories/IncreaseVettedValidatorsLimit.sol b/contracts/EVMScriptFactories/IncreaseVettedValidatorsLimit.sol new file mode 100644 index 00000000..e1948cd8 --- /dev/null +++ b/contracts/EVMScriptFactories/IncreaseVettedValidatorsLimit.sol @@ -0,0 +1,147 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; + +/// @notice Creates EVMScript to increase staking limit for node operator +contract IncreaseVettedValidatorsLimit is IEVMScriptFactory { + struct VettedValidatorsLimitInput { + uint256 nodeOperatorId; + uint256 stakingLimit; + } + struct NodeOperatorData { + uint256 id; + bool active; + address rewardAddress; + uint64 stakingLimit; + uint64 totalSigningKeys; + } + + // ------------- + // CONSTANTS + // ------------- + /// @notice keccak256("MANAGE_SIGNING_KEYS") + bytes32 private constant MANAGE_SIGNING_KEYS_ROLE = + 0x75abc64490e17b40ea1e66691c3eb493647b24430b358bd87ec3e5127f1621ee; + + // ------------- + // ERRORS + // ------------- + + string private constant NODE_OPERATOR_DISABLED = "NODE_OPERATOR_DISABLED"; + string private constant CALLER_IS_NOT_NODE_OPERATOR_OR_MANAGER = + "CALLER_IS_NOT_NODE_OPERATOR_OR_MANAGER"; + string private constant STAKING_LIMIT_TOO_LOW = "STAKING_LIMIT_TOO_LOW"; + string private constant NOT_ENOUGH_SIGNING_KEYS = "NOT_ENOUGH_SIGNING_KEYS"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor(address _nodeOperatorsRegistry) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to increase staking limit for node operator + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded tuple: (uint256 _nodeOperatorId, uint256 _stakingLimit) where + /// _nodeOperatorId - id of node operator in NodeOperatorsRegistry + /// _stakingLimit - new staking limit + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override returns (bytes memory) { + _validateInputData(_creator, _evmScriptCallData); + + return + EVMScriptCreator.createEVMScript( + address(nodeOperatorsRegistry), + nodeOperatorsRegistry.setNodeOperatorStakingLimit.selector, + _evmScriptCallData + ); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded tuple: (uint256 _nodeOperatorId, uint256 _stakingLimit) where + /// _nodeOperatorId - id of node operator in NodeOperatorsRegistry + /// _stakingLimit - new staking limit + /// @return VettedValidatorsLimitInput + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (VettedValidatorsLimitInput memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (VettedValidatorsLimitInput memory) { + return abi.decode(_evmScriptCallData, (VettedValidatorsLimitInput)); + } + + function _validateInputData(address _creator, bytes memory _evmScriptCallData) private view { + VettedValidatorsLimitInput memory vettedValidatorsLimitInput = _decodeEVMScriptCallData( + _evmScriptCallData + ); + + NodeOperatorData memory nodeOperatorData = _getNodeOperatorData( + vettedValidatorsLimitInput.nodeOperatorId + ); + + uint256[] memory role_params = new uint256[](1); + role_params[0] = vettedValidatorsLimitInput.nodeOperatorId; + + require( + _creator == nodeOperatorData.rewardAddress || + nodeOperatorsRegistry.canPerform(_creator, MANAGE_SIGNING_KEYS_ROLE, role_params), + CALLER_IS_NOT_NODE_OPERATOR_OR_MANAGER + ); + require(nodeOperatorData.active, NODE_OPERATOR_DISABLED); + require( + nodeOperatorData.stakingLimit < vettedValidatorsLimitInput.stakingLimit, + STAKING_LIMIT_TOO_LOW + ); + require( + nodeOperatorData.totalSigningKeys >= vettedValidatorsLimitInput.stakingLimit, + NOT_ENOUGH_SIGNING_KEYS + ); + } + + function _getNodeOperatorData( + uint256 _nodeOperatorId + ) private view returns (NodeOperatorData memory _nodeOperatorData) { + ( + bool active, + , + address rewardAddress, + uint64 stakingLimit, + , + uint64 totalSigningKeys, + + ) = nodeOperatorsRegistry.getNodeOperator(_nodeOperatorId, false); + + _nodeOperatorData.id = _nodeOperatorId; + _nodeOperatorData.active = active; + _nodeOperatorData.rewardAddress = rewardAddress; + _nodeOperatorData.stakingLimit = stakingLimit; + _nodeOperatorData.totalSigningKeys = totalSigningKeys; + } +} diff --git a/contracts/EVMScriptFactories/RemoveAllowedRecipient.sol b/contracts/EVMScriptFactories/RemoveAllowedRecipient.sol new file mode 100644 index 00000000..447ab8f5 --- /dev/null +++ b/contracts/EVMScriptFactories/RemoveAllowedRecipient.sol @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +import "../TrustedCaller.sol"; +import "../AllowedRecipientsRegistry.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; + +/// @author psirex, zuzueeka +/// @notice Creates EVMScript to remove allowed recipient address from AllowedRecipientsRegistry +contract RemoveAllowedRecipient is TrustedCaller, IEVMScriptFactory { + // ------------- + // ERRORS + // ------------- + string private constant ERROR_ALLOWED_RECIPIENT_NOT_FOUND = "ALLOWED_RECIPIENT_NOT_FOUND"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of AllowedRecipientsRegistry + AllowedRecipientsRegistry public allowedRecipientsRegistry; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor(address _trustedCaller, address _allowedRecipientsRegistry) + TrustedCaller(_trustedCaller) + { + allowedRecipientsRegistry = AllowedRecipientsRegistry(_allowedRecipientsRegistry); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to remove allowed recipient address from allowedRecipientsRegistry + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded tuple: (address recipientAddress) + function createEVMScript(address _creator, bytes memory _evmScriptCallData) + external + view + override + onlyTrustedCaller(_creator) + returns (bytes memory) + { + require( + allowedRecipientsRegistry.isRecipientAllowed( + _decodeEVMScriptCallData(_evmScriptCallData) + ), + ERROR_ALLOWED_RECIPIENT_NOT_FOUND + ); + return + EVMScriptCreator.createEVMScript( + address(allowedRecipientsRegistry), + allowedRecipientsRegistry.removeRecipient.selector, + _evmScriptCallData + ); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded tuple: (address recipientAddress) + /// @return recipientAddress Address to remove + function decodeEVMScriptCallData(bytes memory _evmScriptCallData) + external + pure + returns (address recipientAddress) + { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData(bytes memory _evmScriptCallData) + private + pure + returns (address) + { + return abi.decode(_evmScriptCallData, (address)); + } +} diff --git a/contracts/EVMScriptFactories/SetNodeOperatorNames.sol b/contracts/EVMScriptFactories/SetNodeOperatorNames.sol new file mode 100644 index 00000000..d44096b5 --- /dev/null +++ b/contracts/EVMScriptFactories/SetNodeOperatorNames.sol @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; + +/// @notice Creates EVMScript to set name of several node operators +contract SetNodeOperatorNames is TrustedCaller, IEVMScriptFactory { + struct SetNameInput { + uint256 nodeOperatorId; + string name; + } + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE = + "NODE_OPERATOR_INDEX_OUT_OF_RANGE"; + string private constant ERROR_WRONG_NAME_LENGTH = "WRONG_NAME_LENGTH"; + string private constant ERROR_SAME_NAME = "SAME_NAME"; + string private constant ERROR_NODE_OPERATORS_IS_NOT_SORTED = "NODE_OPERATORS_IS_NOT_SORTED"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to set name of several node operators + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (SetNameInput[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + SetNameInput[] memory decodedCallData = _decodeEVMScriptCallData(_evmScriptCallData); + + _validateInputData(decodedCallData); + + bytes[] memory nodeOperatorsNamesCalldata = new bytes[](decodedCallData.length); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + nodeOperatorsNamesCalldata[i] = abi.encode( + decodedCallData[i].nodeOperatorId, + decodedCallData[i].name + ); + } + + return + EVMScriptCreator.createEVMScript( + address(nodeOperatorsRegistry), + nodeOperatorsRegistry.setNodeOperatorName.selector, + nodeOperatorsNamesCalldata + ); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (SetNameInput[]) + /// @return SetNameInput[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (SetNameInput[] memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (SetNameInput[] memory) { + return abi.decode(_evmScriptCallData, (SetNameInput[])); + } + + function _validateInputData(SetNameInput[] memory _decodedCallData) private view { + uint256 maxNameLength = nodeOperatorsRegistry.MAX_NODE_OPERATOR_NAME_LENGTH(); + uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); + + require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); + require( + _decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, + ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE + ); + + for (uint256 i = 0; i < _decodedCallData.length; ++i) { + require( + i == 0 || + _decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, + ERROR_NODE_OPERATORS_IS_NOT_SORTED + ); + require( + bytes(_decodedCallData[i].name).length > 0 && + bytes(_decodedCallData[i].name).length <= maxNameLength, + ERROR_WRONG_NAME_LENGTH + ); + + ( + /* bool active */, + string memory name, + /* address rewardAddress */, + /* uint64 stakingLimit */, + /* uint64 stoppedValidators */, + /* uint64 totalSigningKeys */, + /* uint64 usedSigningKeys */ + ) = nodeOperatorsRegistry.getNodeOperator( + _decodedCallData[i].nodeOperatorId, + true + ); + + require( + keccak256(bytes(_decodedCallData[i].name)) != keccak256(bytes(name)), + ERROR_SAME_NAME + ); + } + } +} diff --git a/contracts/EVMScriptFactories/SetNodeOperatorRewardAddresses.sol b/contracts/EVMScriptFactories/SetNodeOperatorRewardAddresses.sol new file mode 100644 index 00000000..05b11c05 --- /dev/null +++ b/contracts/EVMScriptFactories/SetNodeOperatorRewardAddresses.sol @@ -0,0 +1,138 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; + +/// @notice Creates EVMScript to set reward address of several node operators +contract SetNodeOperatorRewardAddresses is TrustedCaller, IEVMScriptFactory { + struct SetRewardAddressInput { + uint256 nodeOperatorId; + address rewardAddress; + } + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE = + "NODE_OPERATOR_INDEX_OUT_OF_RANGE"; + string private constant ERROR_LIDO_REWARD_ADDRESS = "LIDO_REWARD_ADDRESS"; + string private constant ERROR_ZERO_REWARD_ADDRESS = "ZERO_REWARD_ADDRESS"; + string private constant ERROR_SAME_REWARD_ADDRESS = "SAME_REWARD_ADDRESS"; + string private constant ERROR_NODE_OPERATORS_IS_NOT_SORTED = "NODE_OPERATORS_IS_NOT_SORTED"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + /// @notice Address of Lido contract + address public immutable lido; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry, + address _lido + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + lido = _lido; + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to set reward address of several node operators + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (SetRewardAddressInput[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + SetRewardAddressInput[] memory decodedCallData = _decodeEVMScriptCallData( + _evmScriptCallData + ); + + _validateInputData(decodedCallData); + + bytes[] memory nodeOperatorRewardAddressesCalldata = new bytes[](decodedCallData.length); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + nodeOperatorRewardAddressesCalldata[i] = abi.encode( + decodedCallData[i].nodeOperatorId, + decodedCallData[i].rewardAddress + ); + } + return + EVMScriptCreator.createEVMScript( + address(nodeOperatorsRegistry), + nodeOperatorsRegistry.setNodeOperatorRewardAddress.selector, + nodeOperatorRewardAddressesCalldata + ); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (SetRewardAddressInput[]) + /// @return SetRewardAddressInput[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (SetRewardAddressInput[] memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (SetRewardAddressInput[] memory) { + return abi.decode(_evmScriptCallData, (SetRewardAddressInput[])); + } + + function _validateInputData(SetRewardAddressInput[] memory _decodedCallData) private view { + uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); + + require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); + require( + _decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, + ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE + ); + + for (uint256 i = 0; i < _decodedCallData.length; ++i) { + require( + i == 0 || + _decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, + ERROR_NODE_OPERATORS_IS_NOT_SORTED + ); + require(_decodedCallData[i].rewardAddress != lido, ERROR_LIDO_REWARD_ADDRESS); + require(_decodedCallData[i].rewardAddress != address(0), ERROR_ZERO_REWARD_ADDRESS); + + ( + /* bool active */, + /* string memory name */, + address rewardAddress, + /* uint64 stakingLimit */, + /* uint64 stoppedValidators */, + /* uint64 totalSigningKeys */, + /* uint64 usedSigningKeys */ + ) = nodeOperatorsRegistry.getNodeOperator( + _decodedCallData[i].nodeOperatorId, + false + ); + + require(_decodedCallData[i].rewardAddress != rewardAddress, ERROR_SAME_REWARD_ADDRESS); + } + } +} diff --git a/contracts/EVMScriptFactories/SetVettedValidatorsLimits.sol b/contracts/EVMScriptFactories/SetVettedValidatorsLimits.sol new file mode 100644 index 00000000..ebcbf5c3 --- /dev/null +++ b/contracts/EVMScriptFactories/SetVettedValidatorsLimits.sol @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; + +/// @notice Creates EVMScript to set staking limit for node operators +contract SetVettedValidatorsLimits is TrustedCaller, IEVMScriptFactory { + struct VettedValidatorsLimitInput { + uint256 nodeOperatorId; + uint256 stakingLimit; + } + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_NOT_ENOUGH_SIGNING_KEYS = "NOT_ENOUGH_SIGNING_KEYS"; + string private constant ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE = + "NODE_OPERATOR_INDEX_OUT_OF_RANGE"; + string private constant ERROR_NODE_OPERATORS_IS_NOT_SORTED = "NODE_OPERATORS_IS_NOT_SORTED"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + string private constant ERROR_NODE_OPERATOR_IS_NOT_ACTIVE = "NODE_OPERATOR_IS_NOT_ACTIVE"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to set staking limit of several node operators + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (VettedValidatorsLimitInput[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + VettedValidatorsLimitInput[] memory decodedCallData = _decodeEVMScriptCallData( + _evmScriptCallData + ); + + _validateInputData(decodedCallData); + + bytes[] memory setVettedValidatorsLimitsCalldata = new bytes[](decodedCallData.length); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + setVettedValidatorsLimitsCalldata[i] = abi.encode( + decodedCallData[i].nodeOperatorId, + decodedCallData[i].stakingLimit + ); + } + + return + EVMScriptCreator.createEVMScript( + address(nodeOperatorsRegistry), + nodeOperatorsRegistry.setNodeOperatorStakingLimit.selector, + setVettedValidatorsLimitsCalldata + ); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (VettedValidatorsLimitInput[]) + /// @return VettedValidatorsLimitInput[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (VettedValidatorsLimitInput[] memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (VettedValidatorsLimitInput[] memory) { + return abi.decode(_evmScriptCallData, (VettedValidatorsLimitInput[])); + } + + function _validateInputData(VettedValidatorsLimitInput[] memory _decodedCallData) private view { + uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); + require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); + require( + _decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, + ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE + ); + + for (uint256 i = 0; i < _decodedCallData.length; ++i) { + require( + i == 0 || + _decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, + ERROR_NODE_OPERATORS_IS_NOT_SORTED + ); + + ( + bool active, + /* string memory name */, + /* address rewardAddress */, + /* uint64 stakingLimit */, + /* uint64 stoppedValidators */, + uint64 totalSigningKeys, + /* uint64 usedSigningKeys */ + ) = nodeOperatorsRegistry.getNodeOperator( + _decodedCallData[i].nodeOperatorId, + false + ); + + require( + totalSigningKeys >= _decodedCallData[i].stakingLimit, + ERROR_NOT_ENOUGH_SIGNING_KEYS + ); + + require( + active == true, + ERROR_NODE_OPERATOR_IS_NOT_ACTIVE + ); + } + } +} diff --git a/contracts/EVMScriptFactories/TopUpAllowedRecipients.sol b/contracts/EVMScriptFactories/TopUpAllowedRecipients.sol new file mode 100644 index 00000000..10008f12 --- /dev/null +++ b/contracts/EVMScriptFactories/TopUpAllowedRecipients.sol @@ -0,0 +1,159 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +import "../TrustedCaller.sol"; +import "../AllowedRecipientsRegistry.sol"; +import "../interfaces/IFinance.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../EasyTrack.sol"; + +/// @notice Creates EVMScript to top up allowed recipients addresses within the current spendable balance +contract TopUpAllowedRecipients is TrustedCaller, IEVMScriptFactory { + // ------------- + // ERRORS + // ------------- + string private constant ERROR_LENGTH_MISMATCH = "LENGTH_MISMATCH"; + string private constant ERROR_EMPTY_DATA = "EMPTY_DATA"; + string private constant ERROR_ZERO_AMOUNT = "ZERO_AMOUNT"; + string private constant ERROR_RECIPIENT_NOT_ALLOWED = "RECIPIENT_NOT_ALLOWED"; + string private constant ERROR_SUM_EXCEEDS_SPENDABLE_BALANCE = "SUM_EXCEEDS_SPENDABLE_BALANCE"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of EasyTrack contract + EasyTrack public immutable easyTrack; + + /// @notice Address of Aragon's Finance contract + IFinance public immutable finance; + + /// @notice Address of payout token + address public token; + + /// @notice Address of AllowedRecipientsRegistry contract + AllowedRecipientsRegistry public allowedRecipientsRegistry; + + // ------------- + // CONSTRUCTOR + // ------------- + + /// @param _trustedCaller Address that has access to certain methods. + /// Set once on deployment and can't be changed. + /// @param _allowedRecipientsRegistry Address of AllowedRecipientsRegistry contract + /// @param _finance Address of Aragon's Finance contract + /// @param _token Address of payout token + /// @param _easyTrack Address of EasyTrack contract + constructor( + address _trustedCaller, + address _allowedRecipientsRegistry, + address _finance, + address _token, + address _easyTrack + ) TrustedCaller(_trustedCaller) { + finance = IFinance(_finance); + token = _token; + allowedRecipientsRegistry = AllowedRecipientsRegistry(_allowedRecipientsRegistry); + easyTrack = EasyTrack(_easyTrack); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to top up allowed recipients addresses + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded tuple: (address[] recipients, uint256[] amounts) where + /// recipients - addresses of recipients to top up + /// amounts - corresponding amounts of token to transfer + /// @dev note that the arrays below has one extra element to store limit enforcement calls + function createEVMScript(address _creator, bytes memory _evmScriptCallData) + external + view + override + onlyTrustedCaller(_creator) + returns (bytes memory) + { + (address[] memory recipients, uint256[] memory amounts) = _decodeEVMScriptCallData( + _evmScriptCallData + ); + uint256 totalAmount = _validateEVMScriptCallData(recipients, amounts); + + address[] memory to = new address[](recipients.length + 1); + bytes4[] memory methodIds = new bytes4[](recipients.length + 1); + bytes[] memory evmScriptsCalldata = new bytes[](recipients.length + 1); + + to[0] = address(allowedRecipientsRegistry); + methodIds[0] = allowedRecipientsRegistry.updateSpentAmount.selector; + evmScriptsCalldata[0] = abi.encode(totalAmount); + + for (uint256 i = 0; i < recipients.length; ++i) { + to[i + 1] = address(finance); + methodIds[i + 1] = finance.newImmediatePayment.selector; + evmScriptsCalldata[i + 1] = abi.encode( + token, + recipients[i], + amounts[i], + "Easy Track: top up recipient" + ); + } + + return EVMScriptCreator.createEVMScript(to, methodIds, evmScriptsCalldata); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded tuple: (address[] recipients, uint256[] amounts) where + /// recipients - addresses of recipients to top up + /// amounts - corresponding amounts of token to transfer + /// @return recipients Addresses of recipients to top up + /// @return amounts Amounts of token to transfer + function decodeEVMScriptCallData(bytes memory _evmScriptCallData) + external + pure + returns (address[] memory recipients, uint256[] memory amounts) + { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _validateEVMScriptCallData(address[] memory _recipients, uint256[] memory _amounts) + private + view + returns (uint256 totalAmount) + { + require(_amounts.length == _recipients.length, ERROR_LENGTH_MISMATCH); + require(_recipients.length > 0, ERROR_EMPTY_DATA); + + for (uint256 i = 0; i < _recipients.length; ++i) { + require(_amounts[i] > 0, ERROR_ZERO_AMOUNT); + require( + allowedRecipientsRegistry.isRecipientAllowed(_recipients[i]), + ERROR_RECIPIENT_NOT_ALLOWED + ); + totalAmount += _amounts[i]; + } + + _validateSpendableBalance(totalAmount); + } + + function _decodeEVMScriptCallData(bytes memory _evmScriptCallData) + private + pure + returns (address[] memory recipients, uint256[] memory amounts) + { + return abi.decode(_evmScriptCallData, (address[], uint256[])); + } + + function _validateSpendableBalance(uint256 _amount) private view { + require( + allowedRecipientsRegistry.isUnderSpendableBalance(_amount, easyTrack.motionDuration()), + ERROR_SUM_EXCEEDS_SPENDABLE_BALANCE + ); + } +} diff --git a/contracts/EVMScriptFactories/UpdateTargetValidatorLimits.sol b/contracts/EVMScriptFactories/UpdateTargetValidatorLimits.sol new file mode 100644 index 00000000..48a9ea83 --- /dev/null +++ b/contracts/EVMScriptFactories/UpdateTargetValidatorLimits.sol @@ -0,0 +1,125 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.6; + +import "../TrustedCaller.sol"; +import "../libraries/EVMScriptCreator.sol"; +import "../interfaces/IEVMScriptFactory.sol"; +import "../interfaces/INodeOperatorsRegistry.sol"; + +/// @notice Creates EVMScript to set node operators target validators limit +contract UpdateTargetValidatorLimits is TrustedCaller, IEVMScriptFactory { + struct TargetValidatorsLimit { + uint256 nodeOperatorId; + bool isTargetLimitActive; + uint256 targetLimit; + } + + // ------------- + // CONSTANTS + // ------------- + + uint256 internal constant UINT64_MAX = 0xFFFFFFFFFFFFFFFF; + + // ------------- + // ERRORS + // ------------- + + string private constant ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE = + "NODE_OPERATOR_INDEX_OUT_OF_RANGE"; + string private constant ERROR_NODE_OPERATORS_IS_NOT_SORTED = "NODE_OPERATORS_IS_NOT_SORTED"; + string private constant ERROR_TARGET_LIMIT_GREATER_THEN_UINT64 = + "TARGET_LIMIT_GREATER_THEN_UINT64"; + string private constant ERROR_EMPTY_CALLDATA = "EMPTY_CALLDATA"; + + // ------------- + // VARIABLES + // ------------- + + /// @notice Address of NodeOperatorsRegistry contract + INodeOperatorsRegistry public immutable nodeOperatorsRegistry; + + // ------------- + // CONSTRUCTOR + // ------------- + + constructor( + address _trustedCaller, + address _nodeOperatorsRegistry + ) TrustedCaller(_trustedCaller) { + nodeOperatorsRegistry = INodeOperatorsRegistry(_nodeOperatorsRegistry); + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Creates EVMScript to set node operators target validators limit + /// @param _creator Address who creates EVMScript + /// @param _evmScriptCallData Encoded (TargetValidatorsLimit[]) + function createEVMScript( + address _creator, + bytes memory _evmScriptCallData + ) external view override onlyTrustedCaller(_creator) returns (bytes memory) { + TargetValidatorsLimit[] memory decodedCallData = abi.decode( + _evmScriptCallData, + (TargetValidatorsLimit[]) + ); + + _validateInputData(decodedCallData); + + bytes[] memory updateTargetLimitsCallData = new bytes[](decodedCallData.length); + + for (uint256 i = 0; i < decodedCallData.length; ++i) { + updateTargetLimitsCallData[i] = abi.encode(decodedCallData[i]); + } + + return + EVMScriptCreator.createEVMScript( + address(nodeOperatorsRegistry), + nodeOperatorsRegistry.updateTargetValidatorsLimits.selector, + updateTargetLimitsCallData + ); + } + + /// @notice Decodes call data used by createEVMScript method + /// @param _evmScriptCallData Encoded (TargetValidatorsLimit[]) + /// @return TargetValidatorsLimit[] + function decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) external pure returns (TargetValidatorsLimit[] memory) { + return _decodeEVMScriptCallData(_evmScriptCallData); + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + + function _decodeEVMScriptCallData( + bytes memory _evmScriptCallData + ) private pure returns (TargetValidatorsLimit[] memory) { + return abi.decode(_evmScriptCallData, (TargetValidatorsLimit[])); + } + + function _validateInputData(TargetValidatorsLimit[] memory _decodedCallData) private view { + uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); + require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); + require( + _decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, + ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE + ); + + for (uint256 i = 0; i < _decodedCallData.length; ++i) { + require( + i == 0 || + _decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, + ERROR_NODE_OPERATORS_IS_NOT_SORTED + ); + require( + _decodedCallData[i].targetLimit <= UINT64_MAX, + ERROR_TARGET_LIMIT_GREATER_THEN_UINT64 + ); + } + } +} diff --git a/contracts/LimitsChecker.sol b/contracts/LimitsChecker.sol new file mode 100644 index 00000000..b62e643f --- /dev/null +++ b/contracts/LimitsChecker.sol @@ -0,0 +1,336 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +import "./libraries/EVMScriptCreator.sol"; +import "./interfaces/IBokkyPooBahsDateTimeContract.sol"; + +import "OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/AccessControl.sol"; + +/// @author zuzueeka +/// @notice Stores limits params and provides limit-enforcement logic +/// +/// ▲ spendableBalance = limit-spentAmount +/// | +/// │ |................ |.. limit-spentAmount = limit-0 = limit +/// │..... | ... | +/// │ ........| ...... | .............. +/// | .....| +/// │─────────────────────────────────────────────────────────────> Time +/// | ^ | ^ ^ ^ | ^ (^ - Motion enactment) +/// │ |currentPeriodEndTimestamp |currentPeriodEndTimestamp +/// | |spentAmount=0 |spentAmount=0 +/// +/// currentPeriodEndTimestamp is calculated as a calendar date of the beginning of +/// a next month, bi-months, quarter, half year, or year period. +/// If, for example, periodDurationMonths = 3, then it is considered that the date changes once a quarter. +/// And currentPeriodEndTimestamp can take values 1 Apr, 1 Jul, 1 Oct, 1 Jan. +/// If periodDurationMonths = 1, then shift of currentPeriodEndTimestamp occurs once a month +/// and currentPeriodEndTimestamp can take values 1 Feb, 1 Mar, 1 Apr, etc +/// +contract LimitsChecker is AccessControl { + // ------------- + // EVENTS + // ------------- + event LimitsParametersChanged(uint256 _limit, uint256 _periodDurationMonths); + event SpendableAmountChanged( + uint256 _alreadySpentAmount, + uint256 _spendableBalance, + uint256 indexed _periodStartTimestamp, + uint256 _periodEndTimestamp + ); + event CurrentPeriodAdvanced(uint256 indexed _periodStartTimestamp); + event BokkyPooBahsDateTimeContractChanged(address indexed _newAddress); + event SpentAmountChanged(uint256 _newSpentAmount); + + // ------------- + // ERRORS + // ------------- + string private constant ERROR_INVALID_PERIOD_DURATION = "INVALID_PERIOD_DURATION"; + string private constant ERROR_SUM_EXCEEDS_SPENDABLE_BALANCE = "SUM_EXCEEDS_SPENDABLE_BALANCE"; + string private constant ERROR_TOO_LARGE_LIMIT = "TOO_LARGE_LIMIT"; + string private constant ERROR_SAME_DATE_TIME_CONTRACT_ADDRESS = + "SAME_DATE_TIME_CONTRACT_ADDRESS"; + string private constant ERROR_SPENT_AMOUNT_EXCEEDS_LIMIT = "ERROR_SPENT_AMOUNT_EXCEEDS_LIMIT"; + + // ------------- + // ROLES + // ------------- + bytes32 public constant SET_PARAMETERS_ROLE = keccak256("SET_PARAMETERS_ROLE"); + bytes32 public constant UPDATE_SPENT_AMOUNT_ROLE = keccak256("UPDATE_SPENT_AMOUNT_ROLE"); + + // ------------- + // CONSTANTS + // ------------- + + // ------------ + // STORAGE VARIABLES + // ------------ + + /// @notice Address of BokkyPooBahsDateTimeContract + IBokkyPooBahsDateTimeContract public bokkyPooBahsDateTimeContract; + + /// @notice Length of period in months + uint64 internal periodDurationMonths; + + /// @notice End of the current period + uint128 internal currentPeriodEndTimestamp; + + /// @notice The maximum that can be spent in a period + uint128 internal limit; + + /// @notice Amount already spent in the period + uint128 internal spentAmount; + + // ------------ + // CONSTRUCTOR + // ------------ + /// @param _setParametersRoleHolders List of addresses which will + /// be granted with role SET_PARAMETERS_ROLE + /// @param _updateSpentAmountRoleHolders List of addresses which will + /// be granted with role UPDATE_SPENT_AMOUNT_ROLE + /// @param _bokkyPooBahsDateTimeContract Address of bokkyPooBahs DateTime Contract + constructor( + address[] memory _setParametersRoleHolders, + address[] memory _updateSpentAmountRoleHolders, + IBokkyPooBahsDateTimeContract _bokkyPooBahsDateTimeContract + ) { + for (uint256 i = 0; i < _setParametersRoleHolders.length; i++) { + _setupRole(SET_PARAMETERS_ROLE, _setParametersRoleHolders[i]); + } + for (uint256 i = 0; i < _updateSpentAmountRoleHolders.length; i++) { + _setupRole(UPDATE_SPENT_AMOUNT_ROLE, _updateSpentAmountRoleHolders[i]); + } + bokkyPooBahsDateTimeContract = _bokkyPooBahsDateTimeContract; + } + + // ------------- + // EXTERNAL METHODS + // ------------- + + /// @notice Checks if _payoutAmount is less or equal than the may be spent + /// @param _payoutAmount Motion total amount + /// @param _motionDuration Motion duration - minimal time required to pass before enacting of motion + /// @return True if _payoutAmount is less or equal than may be spent + /// @dev note that upfront check is used to compare _paymentSum with total limit in case + /// when motion is started in one period and will be probably enacted in the next. + function isUnderSpendableBalance(uint256 _payoutAmount, uint256 _motionDuration) + external + view + returns (bool) + { + if (block.timestamp + _motionDuration >= currentPeriodEndTimestamp) { + return _payoutAmount <= limit; + } else { + return _payoutAmount <= _spendableBalance(limit, spentAmount); + } + } + + /// @notice Checks if _payoutAmount may be spent and increases spentAmount by _payoutAmount. + /// @notice Also updates the period boundaries if necessary. + function updateSpentAmount(uint256 _payoutAmount) external onlyRole(UPDATE_SPENT_AMOUNT_ROLE) { + uint256 spentAmountLocal = spentAmount; + uint256 limitLocal = limit; + uint256 currentPeriodEndTimestampLocal = currentPeriodEndTimestamp; + + /// When it is necessary to shift the currentPeriodEndTimestamp it takes on a new value. + /// And also spent is set to zero. Thus begins a new period. + if (block.timestamp >= currentPeriodEndTimestampLocal) { + currentPeriodEndTimestampLocal = _getPeriodEndFromTimestamp(block.timestamp); + spentAmountLocal = 0; + emit CurrentPeriodAdvanced( + _getPeriodStartFromTimestamp(currentPeriodEndTimestampLocal - 1) + ); + currentPeriodEndTimestamp = uint128(currentPeriodEndTimestampLocal); + } + + require( + _payoutAmount <= _spendableBalance(limitLocal, spentAmountLocal), + ERROR_SUM_EXCEEDS_SPENDABLE_BALANCE + ); + spentAmountLocal += _payoutAmount; + spentAmount = uint128(spentAmountLocal); + + ( + uint256 alreadySpentAmount, + uint256 spendableBalanceInPeriod, + uint256 periodStartTimestamp, + uint256 periodEndTimestamp + ) = _getCurrentPeriodState(limitLocal, spentAmountLocal, currentPeriodEndTimestampLocal); + + emit SpendableAmountChanged( + alreadySpentAmount, + spendableBalanceInPeriod, + periodStartTimestamp, + periodEndTimestamp + ); + } + + /// @notice Returns balance that can be spent in the current period + /// @notice If period advanced and no call to updateSpentAmount or setLimitParameters made, + /// @notice then the method will return spendable balance corresponding to the previous period. + /// @return Balance that can be spent in the current period + function spendableBalance() external view returns (uint256) { + return _spendableBalance(limit, spentAmount); + } + + /// @notice Sets periodDurationMonths and limit + /// @notice Calculates currentPeriodEndTimestamp as a calendar date of the beginning of next period. + /// @param _limit Limit to set + /// @param _periodDurationMonths Length of period in months. Must be 1, 2, 3, 6 or 12. + function setLimitParameters(uint256 _limit, uint256 _periodDurationMonths) + external + onlyRole(SET_PARAMETERS_ROLE) + { + require(_limit <= type(uint128).max, ERROR_TOO_LARGE_LIMIT); + + _validatePeriodDurationMonths(_periodDurationMonths); + periodDurationMonths = uint64(_periodDurationMonths); + uint256 currentPeriodEndTimestampLocal = _getPeriodEndFromTimestamp(block.timestamp); + emit CurrentPeriodAdvanced( + _getPeriodStartFromTimestamp(currentPeriodEndTimestampLocal - 1) + ); + currentPeriodEndTimestamp = uint128(currentPeriodEndTimestampLocal); + limit = uint128(_limit); + + emit LimitsParametersChanged(_limit, _periodDurationMonths); + } + + /// @notice Returns limit and periodDurationMonths + /// @return limit - the maximum that can be spent in a period + /// @return periodDurationMonths - length of period in months + function getLimitParameters() external view returns (uint256, uint256) { + return (limit, periodDurationMonths); + } + + /// @notice Returns state of the current period: amount spent, balance available for spending, + /// @notice start date of the current period and end date of the current period + /// @notice If period advanced and the period was not shifted, + /// @notice then the method will return spendable balance corresponding to the previous period. + /// @return _alreadySpentAmount - amount already spent in the current period + /// @return _spendableBalanceInPeriod - balance available for spending in the current period + /// @return _periodStartTimestamp - start date of the current period + /// @return _periodEndTimestamp - end date of the current period + function getPeriodState() + external + view + returns ( + uint256 _alreadySpentAmount, + uint256 _spendableBalanceInPeriod, + uint256 _periodStartTimestamp, + uint256 _periodEndTimestamp + ) + { + return _getCurrentPeriodState(limit, spentAmount, currentPeriodEndTimestamp); + } + + /// @notice Sets address of BokkyPooBahsDateTime contract + /// @dev Need this to be able to replace the contract in case of a bug in it + /// @param _bokkyPooBahsDateTimeContract New address of the BokkyPooBahsDateTime library + function setBokkyPooBahsDateTimeContract(address _bokkyPooBahsDateTimeContract) + external + onlyRole(SET_PARAMETERS_ROLE) + { + require( + _bokkyPooBahsDateTimeContract != address(bokkyPooBahsDateTimeContract), + ERROR_SAME_DATE_TIME_CONTRACT_ADDRESS + ); + + bokkyPooBahsDateTimeContract = IBokkyPooBahsDateTimeContract(_bokkyPooBahsDateTimeContract); + emit BokkyPooBahsDateTimeContractChanged(_bokkyPooBahsDateTimeContract); + } + + /// @notice Allows setting the amount of spent tokens in the current period manually + /// @param _newSpentAmount New value for the amount of spent tokens in the current period + function unsafeSetSpentAmount(uint256 _newSpentAmount) external onlyRole(SET_PARAMETERS_ROLE) { + require(_newSpentAmount <= limit, ERROR_SPENT_AMOUNT_EXCEEDS_LIMIT); + + if (spentAmount != _newSpentAmount) { + spentAmount = uint128(_newSpentAmount); + emit SpentAmountChanged(_newSpentAmount); + } + } + + // ------------------ + // PRIVATE METHODS + // ------------------ + function _getCurrentPeriodState( + uint256 _limit, + uint256 _spentAmount, + uint256 _currentPeriodEndTimestamp + ) + internal + view + returns ( + uint256 _alreadySpentAmount, + uint256 _spendableBalanceInPeriod, + uint256 _periodStartTimestamp, + uint256 _periodEndTimestamp + ) + { + return ( + _spentAmount, + _spendableBalance(_limit, _spentAmount), + _getPeriodStartFromTimestamp(_currentPeriodEndTimestamp - 1), + _currentPeriodEndTimestamp + ); + } + + function _spendableBalance(uint256 _limit, uint256 _spentAmount) + internal + pure + returns (uint256) + { + return _spentAmount < _limit ? _limit - _spentAmount : 0; + } + + function _validatePeriodDurationMonths(uint256 _periodDurationMonths) internal pure { + require( + _periodDurationMonths == 1 || + _periodDurationMonths == 2 || + _periodDurationMonths == 3 || + _periodDurationMonths == 6 || + _periodDurationMonths == 12, + ERROR_INVALID_PERIOD_DURATION + ); + } + + function _getPeriodStartFromTimestamp(uint256 _timestamp) internal view returns (uint256) { + // Get year and number of month of the timestamp: + (uint256 year, uint256 month, ) = bokkyPooBahsDateTimeContract.timestampToDate(_timestamp); + // We assume that the year will remain the same, + // because the beginning of the current calendar period will necessarily be in the same year. + uint256 periodStartYear = year; + // Get the number of the start date month: + uint256 periodStartMonth = _getFirstMonthInPeriodFromMonth(month, periodDurationMonths); + // The beginning of the period always matches the calendar date of the beginning of the month. + uint256 periodStartDay = 1; + return + bokkyPooBahsDateTimeContract.timestampFromDate( + periodStartYear, + periodStartMonth, + periodStartDay + ); + } + + function _getFirstMonthInPeriodFromMonth(uint256 _month, uint256 _periodDurationMonths) + internal + pure + returns (uint256 _firstMonthInPeriod) + { + require(_periodDurationMonths != 0, ERROR_INVALID_PERIOD_DURATION); + + // To get the number of the first month in the period: + // 1. get the number of the period within the current year, starting from its beginning: + uint256 periodNumber = (_month - 1) / _periodDurationMonths; + // 2. and then the number of the first month in this period: + _firstMonthInPeriod = periodNumber * _periodDurationMonths + 1; + // The shift by - 1 and then by + 1 happens because the months in the calendar start from 1 and not from 0. + } + + function _getPeriodEndFromTimestamp(uint256 _timestamp) internal view returns (uint256) { + uint256 periodStart = _getPeriodStartFromTimestamp(_timestamp); + return bokkyPooBahsDateTimeContract.addMonths(periodStart, periodDurationMonths); + } +} diff --git a/contracts/interfaces/IACL.sol b/contracts/interfaces/IACL.sol new file mode 100644 index 00000000..485a10da --- /dev/null +++ b/contracts/interfaces/IACL.sol @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +interface IACL { + function grantPermissionP( + address _entity, + address _app, + bytes32 _role, + uint256[] memory _params + ) external; + + function revokePermission(address _entity, address _app, bytes32 _role) external; + + function hasPermission( + address _entity, + address _app, + bytes32 _role + ) external view returns (bool); + + function hasPermission( + address _entity, + address _app, + bytes32 _role, + uint256[] memory _params + ) external view returns (bool); + + function getPermissionParamsLength( + address _entity, + address _app, + bytes32 _role + ) external view returns (uint256); + + function getPermissionParam( + address _entity, + address _app, + bytes32 _role, + uint256 _index + ) external view returns (uint8, uint8, uint240); + + function getPermissionManager(address _app, bytes32 _role) external view returns (address); + + function removePermissionManager(address _app, bytes32 _role) external; +} diff --git a/contracts/interfaces/IBokkyPooBahsDateTimeContract.sol b/contracts/interfaces/IBokkyPooBahsDateTimeContract.sol new file mode 100644 index 00000000..bd16f65e --- /dev/null +++ b/contracts/interfaces/IBokkyPooBahsDateTimeContract.sol @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +/// @author zuzueeka +/// @notice Interface of methods from BokkyPooBahsDateTimeContract to deal with dates +interface IBokkyPooBahsDateTimeContract { + function timestampToDate(uint256 timestamp) + external + pure + returns ( + uint256 year, + uint256 month, + uint256 day + ); + + function timestampFromDate( + uint256 year, + uint256 month, + uint256 day + ) external pure returns (uint256 timestamp); + + function addMonths(uint256 timestamp, uint256 _months) + external + pure + returns (uint256 newTimestamp); +} diff --git a/contracts/interfaces/INodeOperatorsRegistry.sol b/contracts/interfaces/INodeOperatorsRegistry.sol new file mode 100644 index 00000000..f48798d6 --- /dev/null +++ b/contracts/interfaces/INodeOperatorsRegistry.sol @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: 2023 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.4; + +/// @author bulbozaur +interface INodeOperatorsRegistry { + function activateNodeOperator(uint256 _nodeOperatorId) external; + + function deactivateNodeOperator(uint256 _nodeOperatorId) external; + + function getNodeOperatorIsActive(uint256 _nodeOperatorId) external view returns (bool); + + function getNodeOperatorsCount() external view returns (uint256); + + function addNodeOperator( + string memory _name, + address _rewardAddress + ) external returns (uint256 id); + + function MAX_NODE_OPERATOR_NAME_LENGTH() external view returns (uint256); + + function MAX_NODE_OPERATORS_COUNT() external view returns (uint256); + + function setNodeOperatorRewardAddress(uint256 _nodeOperatorId, address _rewardAddress) external; + + function setNodeOperatorName(uint256 _nodeOperatorId, string memory _name) external; + + function getNodeOperator( + uint256 _id, + bool _fullInfo + ) + external + view + returns ( + bool active, + string memory name, + address rewardAddress, + uint64 stakingLimit, + uint64 stoppedValidators, + uint64 totalSigningKeys, + uint64 usedSigningKeys + ); + + function canPerform( + address _sender, + bytes32 _role, + uint256[] memory _params + ) external view returns (bool); + + function setNodeOperatorStakingLimit(uint256 _id, uint64 _stakingLimit) external; + + function updateTargetValidatorsLimits( + uint256 _nodeOperatorId, + bool _isTargetLimitActive, + uint256 _targetLimit + ) external; +} diff --git a/contracts/test/LimitsCheckerWithPrivateViewsExposed.sol.sol b/contracts/test/LimitsCheckerWithPrivateViewsExposed.sol.sol new file mode 100644 index 00000000..4ebf0e78 --- /dev/null +++ b/contracts/test/LimitsCheckerWithPrivateViewsExposed.sol.sol @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2022 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity =0.8.6; + +import "../LimitsChecker.sol"; +import "../interfaces/IBokkyPooBahsDateTimeContract.sol"; +import "../EasyTrack.sol"; + +contract LimitsCheckerWithPrivateViewsExposed is LimitsChecker { + constructor( + address[] memory _setLimitParametersRoleHolders, + address[] memory _updateSpentAmountRoleHolders, + IBokkyPooBahsDateTimeContract _bokkyPooBahsDateTimeContract + ) + LimitsChecker( + _setLimitParametersRoleHolders, + _updateSpentAmountRoleHolders, + _bokkyPooBahsDateTimeContract + ) + {} + + function getFirstMonthInPeriodFromCurrentMonth(uint256 _month) + public + view + returns (uint256 _firstMonthInPeriod) + { + _firstMonthInPeriod = _getFirstMonthInPeriodFromMonth(_month, periodDurationMonths); + } + + function getPeriodStartFromTimestamp(uint256 _timestamp) public view returns (uint256) { + return _getPeriodStartFromTimestamp(_timestamp); + } + + function getPeriodEndFromTimestamp(uint256 _timestamp) public view returns (uint256) { + return _getPeriodEndFromTimestamp(_timestamp); + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/AccessControl.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/AccessControl.sol new file mode 100644 index 00000000..08ab65f6 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/AccessControl.sol @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IAccessControl.sol"; +import "../utils/Context.sol"; +import "../utils/Strings.sol"; +import "../utils/introspection/ERC165.sol"; + +/** + * @dev Contract module that allows children to implement role-based access + * control mechanisms. This is a lightweight version that doesn't allow enumerating role + * members except through off-chain means by accessing the contract event logs. Some + * applications may benefit from on-chain enumerability, for those cases see + * {AccessControlEnumerable}. + * + * Roles are referred to by their `bytes32` identifier. These should be exposed + * in the external API and be unique. The best way to achieve this is by + * using `public constant` hash digests: + * + * ``` + * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); + * ``` + * + * Roles can be used to represent a set of permissions. To restrict access to a + * function call, use {hasRole}: + * + * ``` + * function foo() public { + * require(hasRole(MY_ROLE, msg.sender)); + * ... + * } + * ``` + * + * Roles can be granted and revoked dynamically via the {grantRole} and + * {revokeRole} functions. Each role has an associated admin role, and only + * accounts that have a role's admin role can call {grantRole} and {revokeRole}. + * + * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means + * that only accounts with this role will be able to grant or revoke other + * roles. More complex role relationships can be created by using + * {_setRoleAdmin}. + * + * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to + * grant and revoke this role. Extra precautions should be taken to secure + * accounts that have been granted it. + */ +abstract contract AccessControl is Context, IAccessControl, ERC165 { + struct RoleData { + mapping(address => bool) members; + bytes32 adminRole; + } + + mapping(bytes32 => RoleData) private _roles; + + bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; + + /** + * @dev Modifier that checks that an account has a specific role. Reverts + * with a standardized message including the required role. + * + * The format of the revert reason is given by the following regular expression: + * + * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ + * + * _Available since v4.1._ + */ + modifier onlyRole(bytes32 role) { + _checkRole(role, _msgSender()); + _; + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); + } + + /** + * @dev Returns `true` if `account` has been granted `role`. + */ + function hasRole(bytes32 role, address account) public view override returns (bool) { + return _roles[role].members[account]; + } + + /** + * @dev Revert with a standard message if `account` is missing `role`. + * + * The format of the revert reason is given by the following regular expression: + * + * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ + */ + function _checkRole(bytes32 role, address account) internal view { + if (!hasRole(role, account)) { + revert( + string( + abi.encodePacked( + "AccessControl: account ", + Strings.toHexString(uint160(account), 20), + " is missing role ", + Strings.toHexString(uint256(role), 32) + ) + ) + ); + } + } + + /** + * @dev Returns the admin role that controls `role`. See {grantRole} and + * {revokeRole}. + * + * To change a role's admin, use {_setRoleAdmin}. + */ + function getRoleAdmin(bytes32 role) public view override returns (bytes32) { + return _roles[role].adminRole; + } + + /** + * @dev Grants `role` to `account`. + * + * If `account` had not been already granted `role`, emits a {RoleGranted} + * event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { + _grantRole(role, account); + } + + /** + * @dev Revokes `role` from `account`. + * + * If `account` had been granted `role`, emits a {RoleRevoked} event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { + _revokeRole(role, account); + } + + /** + * @dev Revokes `role` from the calling account. + * + * Roles are often managed via {grantRole} and {revokeRole}: this function's + * purpose is to provide a mechanism for accounts to lose their privileges + * if they are compromised (such as when a trusted device is misplaced). + * + * If the calling account had been granted `role`, emits a {RoleRevoked} + * event. + * + * Requirements: + * + * - the caller must be `account`. + */ + function renounceRole(bytes32 role, address account) public virtual override { + require(account == _msgSender(), "AccessControl: can only renounce roles for self"); + + _revokeRole(role, account); + } + + /** + * @dev Grants `role` to `account`. + * + * If `account` had not been already granted `role`, emits a {RoleGranted} + * event. Note that unlike {grantRole}, this function doesn't perform any + * checks on the calling account. + * + * [WARNING] + * ==== + * This function should only be called from the constructor when setting + * up the initial roles for the system. + * + * Using this function in any other way is effectively circumventing the admin + * system imposed by {AccessControl}. + * ==== + */ + function _setupRole(bytes32 role, address account) internal virtual { + _grantRole(role, account); + } + + /** + * @dev Sets `adminRole` as ``role``'s admin role. + * + * Emits a {RoleAdminChanged} event. + */ + function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { + bytes32 previousAdminRole = getRoleAdmin(role); + _roles[role].adminRole = adminRole; + emit RoleAdminChanged(role, previousAdminRole, adminRole); + } + + function _grantRole(bytes32 role, address account) private { + if (!hasRole(role, account)) { + _roles[role].members[account] = true; + emit RoleGranted(role, account, _msgSender()); + } + } + + function _revokeRole(bytes32 role, address account) private { + if (hasRole(role, account)) { + _roles[role].members[account] = false; + emit RoleRevoked(role, account, _msgSender()); + } + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/IAccessControl.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/IAccessControl.sol new file mode 100644 index 00000000..46147924 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/IAccessControl.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev External interface of AccessControl declared to support ERC165 detection. + */ +interface IAccessControl { + /** + * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` + * + * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite + * {RoleAdminChanged} not being emitted signaling this. + * + * _Available since v3.1._ + */ + event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); + + /** + * @dev Emitted when `account` is granted `role`. + * + * `sender` is the account that originated the contract call, an admin role + * bearer except when using {AccessControl-_setupRole}. + */ + event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); + + /** + * @dev Emitted when `account` is revoked `role`. + * + * `sender` is the account that originated the contract call: + * - if using `revokeRole`, it is the admin role bearer + * - if using `renounceRole`, it is the role bearer (i.e. `account`) + */ + event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); + + /** + * @dev Returns `true` if `account` has been granted `role`. + */ + function hasRole(bytes32 role, address account) external view returns (bool); + + /** + * @dev Returns the admin role that controls `role`. See {grantRole} and + * {revokeRole}. + * + * To change a role's admin, use {AccessControl-_setRoleAdmin}. + */ + function getRoleAdmin(bytes32 role) external view returns (bytes32); + + /** + * @dev Grants `role` to `account`. + * + * If `account` had not been already granted `role`, emits a {RoleGranted} + * event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function grantRole(bytes32 role, address account) external; + + /** + * @dev Revokes `role` from `account`. + * + * If `account` had been granted `role`, emits a {RoleRevoked} event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function revokeRole(bytes32 role, address account) external; + + /** + * @dev Revokes `role` from the calling account. + * + * Roles are often managed via {grantRole} and {revokeRole}: this function's + * purpose is to provide a mechanism for accounts to lose their privileges + * if they are compromised (such as when a trusted device is misplaced). + * + * If the calling account had been granted `role`, emits a {RoleRevoked} + * event. + * + * Requirements: + * + * - the caller must be `account`. + */ + function renounceRole(bytes32 role, address account) external; +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/Ownable.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/Ownable.sol new file mode 100644 index 00000000..16469d5a --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/access/Ownable.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../utils/Context.sol"; + +/** + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * By default, the owner account will be the one that deploys the contract. This + * can later be changed with {transferOwnership}. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be applied to your functions to restrict their use to + * the owner. + */ +abstract contract Ownable is Context { + address private _owner; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /** + * @dev Initializes the contract setting the deployer as the initial owner. + */ + constructor() { + _setOwner(_msgSender()); + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view virtual returns (address) { + return _owner; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(owner() == _msgSender(), "Ownable: caller is not the owner"); + _; + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby removing any functionality that is only available to the owner. + */ + function renounceOwnership() public virtual onlyOwner { + _setOwner(address(0)); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public virtual onlyOwner { + require(newOwner != address(0), "Ownable: new owner is the zero address"); + _setOwner(newOwner); + } + + function _setOwner(address newOwner) private { + address oldOwner = _owner; + _owner = newOwner; + emit OwnershipTransferred(oldOwner, newOwner); + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/security/Pausable.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/security/Pausable.sol new file mode 100644 index 00000000..3c943ce4 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/security/Pausable.sol @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../utils/Context.sol"; + +/** + * @dev Contract module which allows children to implement an emergency stop + * mechanism that can be triggered by an authorized account. + * + * This module is used through inheritance. It will make available the + * modifiers `whenNotPaused` and `whenPaused`, which can be applied to + * the functions of your contract. Note that they will not be pausable by + * simply including this module, only once the modifiers are put in place. + */ +abstract contract Pausable is Context { + /** + * @dev Emitted when the pause is triggered by `account`. + */ + event Paused(address account); + + /** + * @dev Emitted when the pause is lifted by `account`. + */ + event Unpaused(address account); + + bool private _paused; + + /** + * @dev Initializes the contract in unpaused state. + */ + constructor() { + _paused = false; + } + + /** + * @dev Returns true if the contract is paused, and false otherwise. + */ + function paused() public view virtual returns (bool) { + return _paused; + } + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + * + * Requirements: + * + * - The contract must not be paused. + */ + modifier whenNotPaused() { + require(!paused(), "Pausable: paused"); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + * + * Requirements: + * + * - The contract must be paused. + */ + modifier whenPaused() { + require(paused(), "Pausable: not paused"); + _; + } + + /** + * @dev Triggers stopped state. + * + * Requirements: + * + * - The contract must not be paused. + */ + function _pause() internal virtual whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + /** + * @dev Returns to normal state. + * + * Requirements: + * + * - The contract must be paused. + */ + function _unpause() internal virtual whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Address.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Address.sol new file mode 100644 index 00000000..0bb4a55e --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Address.sol @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Collection of functions related to the address type + */ +library Address { + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + */ + function isContract(address account) internal view returns (bool) { + // This method relies on extcodesize, which returns 0 for contracts in + // construction, since the code is only stored at the end of the + // constructor execution. + + uint256 size; + assembly { + size := extcodesize(account) + } + return size > 0; + } + + /** + * @dev Replacement for Solidity's `transfer`: sends `amount` wei to + * `recipient`, forwarding all available gas and reverting on errors. + * + * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost + * of certain opcodes, possibly making contracts go over the 2300 gas limit + * imposed by `transfer`, making them unable to receive funds via + * `transfer`. {sendValue} removes this limitation. + * + * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. + * + * IMPORTANT: because control is transferred to `recipient`, care must be + * taken to not create reentrancy vulnerabilities. Consider using + * {ReentrancyGuard} or the + * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. + */ + function sendValue(address payable recipient, uint256 amount) internal { + require(address(this).balance >= amount, "Address: insufficient balance"); + + (bool success, ) = recipient.call{value: amount}(""); + require(success, "Address: unable to send value, recipient may have reverted"); + } + + /** + * @dev Performs a Solidity function call using a low level `call`. A + * plain `call` is an unsafe replacement for a function call: use this + * function instead. + * + * If `target` reverts with a revert reason, it is bubbled up by this + * function (like regular Solidity function calls). + * + * Returns the raw returned data. To convert to the expected return value, + * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. + * + * Requirements: + * + * - `target` must be a contract. + * - calling `target` with `data` must not revert. + * + * _Available since v3.1._ + */ + function functionCall(address target, bytes memory data) internal returns (bytes memory) { + return functionCall(target, data, "Address: low-level call failed"); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with + * `errorMessage` as a fallback revert reason when `target` reverts. + * + * _Available since v3.1._ + */ + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, 0, errorMessage); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but also transferring `value` wei to `target`. + * + * Requirements: + * + * - the calling contract must have an ETH balance of at least `value`. + * - the called Solidity function must be `payable`. + * + * _Available since v3.1._ + */ + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); + } + + /** + * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but + * with `errorMessage` as a fallback revert reason when `target` reverts. + * + * _Available since v3.1._ + */ + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) internal returns (bytes memory) { + require(address(this).balance >= value, "Address: insufficient balance for call"); + require(isContract(target), "Address: call to non-contract"); + + (bool success, bytes memory returndata) = target.call{value: value}(data); + return verifyCallResult(success, returndata, errorMessage); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a static call. + * + * _Available since v3.3._ + */ + function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { + return functionStaticCall(target, data, "Address: low-level static call failed"); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], + * but performing a static call. + * + * _Available since v3.3._ + */ + function functionStaticCall( + address target, + bytes memory data, + string memory errorMessage + ) internal view returns (bytes memory) { + require(isContract(target), "Address: static call to non-contract"); + + (bool success, bytes memory returndata) = target.staticcall(data); + return verifyCallResult(success, returndata, errorMessage); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a delegate call. + * + * _Available since v3.4._ + */ + function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { + return functionDelegateCall(target, data, "Address: low-level delegate call failed"); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], + * but performing a delegate call. + * + * _Available since v3.4._ + */ + function functionDelegateCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + require(isContract(target), "Address: delegate call to non-contract"); + + (bool success, bytes memory returndata) = target.delegatecall(data); + return verifyCallResult(success, returndata, errorMessage); + } + + /** + * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the + * revert reason using the provided one. + * + * _Available since v4.3._ + */ + function verifyCallResult( + bool success, + bytes memory returndata, + string memory errorMessage + ) internal pure returns (bytes memory) { + if (success) { + return returndata; + } else { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(errorMessage); + } + } + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Context.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Context.sol new file mode 100644 index 00000000..d03dc5f4 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Context.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + */ +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/StorageSlot.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/StorageSlot.sol new file mode 100644 index 00000000..00aa4ec6 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/StorageSlot.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Library for reading and writing primitive types to specific storage slots. + * + * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. + * This library helps with reading and writing to such slots without the need for inline assembly. + * + * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. + * + * Example usage to set ERC1967 implementation slot: + * ``` + * contract ERC1967 { + * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + * + * function _getImplementation() internal view returns (address) { + * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + * } + * + * function _setImplementation(address newImplementation) internal { + * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); + * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + * } + * } + * ``` + * + * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ + */ +library StorageSlot { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + /** + * @dev Returns an `AddressSlot` with member `value` located at `slot`. + */ + function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BooleanSlot` with member `value` located at `slot`. + */ + function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. + */ + function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Uint256Slot` with member `value` located at `slot`. + */ + function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { + assembly { + r.slot := slot + } + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Strings.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Strings.sol new file mode 100644 index 00000000..8f3d41e7 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/Strings.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev String operations. + */ +library Strings { + bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; + + /** + * @dev Converts a `uint256` to its ASCII `string` decimal representation. + */ + function toString(uint256 value) internal pure returns (string memory) { + // Inspired by OraclizeAPI's implementation - MIT licence + // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol + + if (value == 0) { + return "0"; + } + uint256 temp = value; + uint256 digits; + while (temp != 0) { + digits++; + temp /= 10; + } + bytes memory buffer = new bytes(digits); + while (value != 0) { + digits -= 1; + buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); + value /= 10; + } + return string(buffer); + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. + */ + function toHexString(uint256 value) internal pure returns (string memory) { + if (value == 0) { + return "0x00"; + } + uint256 temp = value; + uint256 length = 0; + while (temp != 0) { + length++; + temp >>= 8; + } + return toHexString(value, length); + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. + */ + function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { + bytes memory buffer = new bytes(2 * length + 2); + buffer[0] = "0"; + buffer[1] = "x"; + for (uint256 i = 2 * length + 1; i > 1; --i) { + buffer[i] = _HEX_SYMBOLS[value & 0xf]; + value >>= 4; + } + require(value == 0, "Strings: hex length insufficient"); + return string(buffer); + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/introspection/ERC165.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/introspection/ERC165.sol new file mode 100644 index 00000000..fc9b52f1 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/introspection/ERC165.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "./IERC165.sol"; + +/** + * @dev Implementation of the {IERC165} interface. + * + * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check + * for the additional interface id that will be supported. For example: + * + * ```solidity + * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); + * } + * ``` + * + * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. + */ +abstract contract ERC165 is IERC165 { + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return interfaceId == type(IERC165).interfaceId; + } +} diff --git a/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/introspection/IERC165.sol b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/introspection/IERC165.sol new file mode 100644 index 00000000..01c9c086 --- /dev/null +++ b/dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2/contracts/utils/introspection/IERC165.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC165 standard, as defined in the + * https://eips.ethereum.org/EIPS/eip-165[EIP]. + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others ({ERC165Checker}). + * + * For an implementation, see {ERC165}. + */ +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/deployed-holesky.json b/deployed-holesky.json new file mode 100644 index 00000000..3694da94 --- /dev/null +++ b/deployed-holesky.json @@ -0,0 +1 @@ +{"AddNodeOperators": {"contract": "AddNodeOperators", "address": "0xeF5233A5bbF243149E35B353A73FFa8931FDA02b", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6", "0xfd1E42595CeC3E83239bf8dFc535250e7F48E0bC"]}, "ActivateNodeOperators": {"contract": "ActivateNodeOperators", "address": "0x5b4A9048176D5bA182ceec8e673D8aA6927A40D6", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6", "0xfd1E42595CeC3E83239bf8dFc535250e7F48E0bC"]}, "DeactivateNodeOperators": {"contract": "DeactivateNodeOperators", "address": "0x88d247cdf4ff4A4AAA8B3DD9dd22D1b89219FB3B", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6", "0xfd1E42595CeC3E83239bf8dFc535250e7F48E0bC"]}, "SetVettedValidatorsLimits": {"contract": "SetVettedValidatorsLimits", "address": "0x30Cb36DBb0596aD9Cf5159BD2c4B1456c18e47E8", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6"]}, "SetNodeOperatorNames": {"contract": "SetNodeOperatorNames", "address": "0x4792BaC0a262200fA7d3b68e7622bFc1c2c3a72d", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6"]}, "SetNodeOperatorRewardAddresses": {"contract": "SetNodeOperatorRewardAddresses", "address": "0x6Bfc576018C7f3D2a9180974E5c8e6CFa021f617", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6"]}, "UpdateTargetValidatorLimits": {"contract": "UpdateTargetValidatorLimits", "address": "0xC91a676A69Eb49be9ECa1954fE6fc861AE07A9A2", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6"]}, "ChangeNodeOperatorManagers": {"contract": "ChangeNodeOperatorManagers", "address": "0xb8C4728bc0826bA5864D02FA53148de7A44C2f7E", "constructorArgs": ["0xD76001b33b23452243E2FDa833B6e7B8E3D43198", "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6", "0xfd1E42595CeC3E83239bf8dFc535250e7F48E0bC"]}} \ No newline at end of file diff --git a/deployed-mainnet.json b/deployed-mainnet.json new file mode 100644 index 00000000..76162b9a --- /dev/null +++ b/deployed-mainnet.json @@ -0,0 +1,80 @@ +{ + "AddNodeOperators": { + "contract": "AddNodeOperators", + "address": "0xcAa3AF7460E83E665EEFeC73a7a542E5005C9639", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "0x9895F0F17cc1d1891b6f18ee0b483B6f221b37Bb", + "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84" + ] + }, + "ActivateNodeOperators": { + "contract": "ActivateNodeOperators", + "address": "0xCBb418F6f9BFd3525CE6aADe8F74ECFEfe2DB5C8", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "0x9895F0F17cc1d1891b6f18ee0b483B6f221b37Bb" + ] + }, + "DeactivateNodeOperators": { + "contract": "DeactivateNodeOperators", + "address": "0x8B82C1546D47330335a48406cc3a50Da732672E7", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "0x9895F0F17cc1d1891b6f18ee0b483B6f221b37Bb" + ] + }, + "SetVettedValidatorsLimits": { + "contract": "SetVettedValidatorsLimits", + "address": "0xD75778b855886Fc5e1eA7D6bFADA9EB68b35C19D", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" + ] + }, + "IncreaseVettedValidatorsLimit": { + "contract": "IncreaseVettedValidatorsLimit", + "address": "0xcc993499E03DdA45ae8804AA1620257A1d7FB996", + "constructorArgs": [ + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" + ] + }, + "SetNodeOperatorNames": { + "contract": "SetNodeOperatorNames", + "address": "0x7d509BFF310d9460b1F613e4e40d342201a83Ae4", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" + ] + }, + "SetNodeOperatorRewardAddresses": { + "contract": "SetNodeOperatorRewardAddresses", + "address": "0x589e298964b9181D9938B84bB034C3BB9024E2C0", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84" + ] + }, + "UpdateTargetValidatorLimits": { + "contract": "UpdateTargetValidatorLimits", + "address": "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" + ] + }, + "ChangeNodeOperatorManagers": { + "contract": "ChangeNodeOperatorManagers", + "address": "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D", + "constructorArgs": [ + "0x08637515E85A4633E23dfc7861e2A9f53af640f7", + "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "0x9895F0F17cc1d1891b6f18ee0b483B6f221b37Bb" + ] + } + } + \ No newline at end of file diff --git a/diffyscan-holesky-config.json b/diffyscan-holesky-config.json new file mode 100644 index 00000000..bd77de6d --- /dev/null +++ b/diffyscan-holesky-config.json @@ -0,0 +1,18 @@ +{ + "contracts": { + "TBD":"TBD" + }, + "explorer_hostname": "api-holesky.etherscan.io", + "github_repo": { + "url": "https://github.com/lidofinance/easy-track", + "commit": "TBD", + "relative_root": "" + }, + "dependencies": { + "@openzeppelin/contracts-v4.3.2": { + "url": "https://github.com/OpenZeppelin/openzeppelin-contracts", + "commit": "0c4de6721d9668d7b5b2c5a9400fd0b2a5e8de90", + "relative_root": "contracts" + } + } +} \ No newline at end of file diff --git a/ganache.sh b/ganache.sh new file mode 100755 index 00000000..81d1e40f --- /dev/null +++ b/ganache.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +npx ganache-cli "$@" diff --git a/interfaces/AragonAppProxy.json b/interfaces/AragonAppProxy.json new file mode 100644 index 00000000..5ea64419 --- /dev/null +++ b/interfaces/AragonAppProxy.json @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"proxyType","outputs":[{"name":"proxyTypeId","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"isDepositable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"},{"name":"_initializePayload","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"ProxyDeposit","type":"event"}] \ No newline at end of file diff --git a/interfaces/Kernel.json b/interfaces/Kernel.json new file mode 100644 index 00000000..363c1d16 --- /dev/null +++ b/interfaces/Kernel.json @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KERNEL_APP_ID","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"APP_ADDR_NAMESPACE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"},{"name":"_initializePayload","type":"bytes"},{"name":"_setDefault","type":"bool"}],"name":"newAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"bytes32"}],"name":"apps","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_baseAcl","type":"address"},{"name":"_permissionsCreator","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"CORE_NAMESPACE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"}],"name":"newAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"recoveryVaultAppId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recoveryVaultAppId","type":"bytes32"}],"name":"setRecoveryVaultAppId","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"APP_MANAGER_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"}],"name":"newPinnedAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_namespace","type":"bytes32"},{"name":"_appId","type":"bytes32"},{"name":"_app","type":"address"}],"name":"setApp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_namespace","type":"bytes32"},{"name":"_appId","type":"bytes32"}],"name":"getApp","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"},{"name":"_initializePayload","type":"bytes"},{"name":"_setDefault","type":"bool"}],"name":"newPinnedAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"},{"name":"_initializePayload","type":"bytes"}],"name":"newAppProxyPinned","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"APP_BASES_NAMESPACE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"acl","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"}],"name":"newAppProxy","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"DEFAULT_ACL_APP_ID","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"},{"name":"_initializePayload","type":"bytes"}],"name":"newAppProxy","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"},{"name":"_how","type":"bytes"}],"name":"hasPermission","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"}],"name":"newAppProxyPinned","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_shouldPetrify","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proxy","type":"address"},{"indexed":false,"name":"isUpgradeable","type":"bool"},{"indexed":false,"name":"appId","type":"bytes32"}],"name":"NewAppProxy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"namespace","type":"bytes32"},{"indexed":true,"name":"appId","type":"bytes32"},{"indexed":false,"name":"app","type":"address"}],"name":"SetApp","type":"event"}] \ No newline at end of file diff --git a/interfaces/Lido.json b/interfaces/Lido.json index 7e88271d..c5a3f659 100644 --- a/interfaces/Lido.json +++ b/interfaces/Lido.json @@ -12,7 +12,12 @@ "constant": true, "inputs": [], "name": "name", - "outputs": [{ "name": "", "type": "string" }], + "outputs": [ + { + "name": "", + "type": "string" + } + ], "payable": false, "stateMutability": "pure", "type": "function" @@ -30,7 +35,12 @@ "constant": true, "inputs": [], "name": "hasInitialized", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -38,53 +48,83 @@ { "constant": false, "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_amount", "type": "uint256" } + { + "name": "_spender", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } ], "name": "approve", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, - "inputs": [ - { "name": "depositContract", "type": "address" }, - { "name": "_oracle", "type": "address" }, - { "name": "_operators", "type": "address" }, - { "name": "_treasury", "type": "address" }, - { "name": "_insuranceFund", "type": "address" } + "constant": true, + "inputs": [], + "name": "STAKING_CONTROL_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } ], - "name": "initialize", - "outputs": [], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], - "name": "getInsuranceFund", - "outputs": [{ "name": "", "type": "address" }], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [{ "name": "", "type": "uint256" }], + "inputs": [ + { + "name": "_ethAmount", + "type": "uint256" + } + ], + "name": "getSharesByPooledEth", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [{ "name": "_ethAmount", "type": "uint256" }], - "name": "getSharesByPooledEth", - "outputs": [{ "name": "", "type": "uint256" }], + "inputs": [], + "name": "isStakingPaused", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -92,39 +132,109 @@ { "constant": false, "inputs": [ - { "name": "_sender", "type": "address" }, - { "name": "_recipient", "type": "address" }, - { "name": "_amount", "type": "uint256" } + { + "name": "_sender", + "type": "address" + }, + { + "name": "_recipient", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } ], "name": "transferFrom", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, - "inputs": [], - "name": "getOperators", - "outputs": [{ "name": "", "type": "address" }], + "inputs": [ + { + "name": "_script", + "type": "bytes" + } + ], + "name": "getEVMScriptExecutor", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_maxStakeLimit", + "type": "uint256" + }, + { + "name": "_stakeLimitIncreasePerBlock", + "type": "uint256" + } + ], + "name": "setStakingLimit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, - "inputs": [{ "name": "_script", "type": "bytes" }], - "name": "getEVMScriptExecutor", - "outputs": [{ "name": "", "type": "address" }], + "inputs": [], + "name": "RESUME_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_lidoLocator", + "type": "address" + }, + { + "name": "_eip712StETH", + "type": "address" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, "inputs": [], "name": "decimals", - "outputs": [{ "name": "", "type": "uint8" }], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], "payable": false, "stateMutability": "pure", "type": "function" @@ -133,7 +243,12 @@ "constant": true, "inputs": [], "name": "getRecoveryVault", - "outputs": [{ "name": "", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -141,8 +256,13 @@ { "constant": true, "inputs": [], - "name": "DEPOSIT_SIZE", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -151,16 +271,40 @@ "constant": true, "inputs": [], "name": "getTotalPooledEther", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_newDepositedValidators", + "type": "uint256" + } + ], + "name": "unsafeChangeDepositedValidators", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, "inputs": [], "name": "PAUSE_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -168,11 +312,22 @@ { "constant": false, "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_addedValue", "type": "uint256" } + { + "name": "_spender", + "type": "address" + }, + { + "name": "_addedValue", + "type": "uint256" + } ], "name": "increaseAllowance", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -181,7 +336,12 @@ "constant": true, "inputs": [], "name": "getTreasury", - "outputs": [{ "name": "", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -189,8 +349,13 @@ { "constant": true, "inputs": [], - "name": "SET_ORACLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "isStopped", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -198,26 +363,54 @@ { "constant": true, "inputs": [], - "name": "isStopped", - "outputs": [{ "name": "", "type": "bool" }], + "name": "getBufferedEther", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, + "constant": false, + "inputs": [ + { + "name": "_lidoLocator", + "type": "address" + }, + { + "name": "_eip712StETH", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, "inputs": [], - "name": "MANAGE_WITHDRAWAL_KEY", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", + "name": "receiveELRewards", + "outputs": [], + "payable": true, + "stateMutability": "payable", "type": "function" }, { "constant": true, "inputs": [], - "name": "getBufferedEther", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "getWithdrawalCredentials", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -225,8 +418,13 @@ { "constant": true, "inputs": [], - "name": "SIGNATURE_LENGTH", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "getCurrentStakeLimit", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -234,57 +432,180 @@ { "constant": true, "inputs": [], - "name": "getWithdrawalCredentials", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "getStakeLimitFullInfo", + "outputs": [ + { + "name": "isStakingPaused", + "type": "bool" + }, + { + "name": "isStakingLimitSet", + "type": "bool" + }, + { + "name": "currentStakeLimit", + "type": "uint256" + }, + { + "name": "maxStakeLimit", + "type": "uint256" + }, + { + "name": "maxStakeLimitGrowthBlocks", + "type": "uint256" + }, + { + "name": "prevStakeLimit", + "type": "uint256" + }, + { + "name": "prevStakeBlockNumber", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_sender", + "type": "address" + }, + { + "name": "_recipient", + "type": "address" + }, + { + "name": "_sharesAmount", + "type": "uint256" + } + ], + "name": "transferSharesFrom", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, - "inputs": [{ "name": "_account", "type": "address" }], + "inputs": [ + { + "name": "_account", + "type": "address" + } + ], "name": "balanceOf", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [], + "name": "resumeStaking", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, "inputs": [], "name": "getFeeDistribution", "outputs": [ - { "name": "treasuryFeeBasisPoints", "type": "uint16" }, - { "name": "insuranceFeeBasisPoints", "type": "uint16" }, - { "name": "operatorsFeeBasisPoints", "type": "uint16" } + { + "name": "treasuryFeeBasisPoints", + "type": "uint16" + }, + { + "name": "insuranceFeeBasisPoints", + "type": "uint16" + }, + { + "name": "operatorsFeeBasisPoints", + "type": "uint16" + } ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [], + "name": "receiveWithdrawals", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, { "constant": true, - "inputs": [{ "name": "_sharesAmount", "type": "uint256" }], + "inputs": [ + { + "name": "_sharesAmount", + "type": "uint256" + } + ], "name": "getPooledEthByShares", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [{ "name": "_oracle", "type": "address" }], - "name": "setOracle", - "outputs": [], + "constant": true, + "inputs": [ + { + "name": "token", + "type": "address" + } + ], + "name": "allowRecoverability", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [{ "name": "token", "type": "address" }], - "name": "allowRecoverability", - "outputs": [{ "name": "", "type": "bool" }], + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -293,7 +614,12 @@ "constant": true, "inputs": [], "name": "appId", - "outputs": [{ "name": "", "type": "bytes32" }], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -302,7 +628,12 @@ "constant": true, "inputs": [], "name": "getOracle", - "outputs": [{ "name": "", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -310,39 +641,76 @@ { "constant": true, "inputs": [], - "name": "getInitializationBlock", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "eip712Domain", + "outputs": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [ - { "name": "_treasuryFeeBasisPoints", "type": "uint16" }, - { "name": "_insuranceFeeBasisPoints", "type": "uint16" }, - { "name": "_operatorsFeeBasisPoints", "type": "uint16" } + "constant": true, + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "name": "", + "type": "uint256" + } ], - "name": "setFeeDistribution", - "outputs": [], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [{ "name": "_feeBasisPoints", "type": "uint16" }], - "name": "setFee", - "outputs": [], + "constant": true, + "inputs": [], + "name": "getInitializationBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [{ "name": "_maxDeposits", "type": "uint256" }], - "name": "depositBufferedEther", - "outputs": [], + "inputs": [ + { + "name": "_recipient", + "type": "address" + }, + { + "name": "_sharesAmount", + "type": "uint256" + } + ], + "name": "transferShares", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -351,7 +719,12 @@ "constant": true, "inputs": [], "name": "symbol", - "outputs": [{ "name": "", "type": "string" }], + "outputs": [ + { + "name": "", + "type": "string" + } + ], "payable": false, "stateMutability": "pure", "type": "function" @@ -359,57 +732,110 @@ { "constant": true, "inputs": [], - "name": "MANAGE_FEE", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "getEIP712StETH", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [{ "name": "_token", "type": "address" }], + "inputs": [ + { + "name": "", + "type": "address" + } + ], "name": "transferToVault", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, - { - "constant": true, - "inputs": [], - "name": "SET_TREASURY", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, { "constant": true, "inputs": [ - { "name": "_sender", "type": "address" }, - { "name": "_role", "type": "bytes32" }, - { "name": "_params", "type": "uint256[]" } + { + "name": "_sender", + "type": "address" + }, + { + "name": "_role", + "type": "bytes32" + }, + { + "name": "_params", + "type": "uint256[]" + } ], "name": "canPerform", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [{ "name": "_referral", "type": "address" }], + "inputs": [ + { + "name": "_referral", + "type": "address" + } + ], "name": "submit", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": true, "stateMutability": "payable", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, "inputs": [], - "name": "WITHDRAWAL_CREDENTIALS_LENGTH", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "getEVMScriptRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -417,11 +843,44 @@ { "constant": false, "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_subtractedValue", "type": "uint256" } + { + "name": "_recipient", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } ], - "name": "decreaseAllowance", - "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_maxDepositsCount", + "type": "uint256" + }, + { + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "name": "_depositCalldata", + "type": "bytes" + } + ], + "name": "deposit", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -429,8 +888,13 @@ { "constant": true, "inputs": [], - "name": "getEVMScriptRegistry", - "outputs": [{ "name": "", "type": "address" }], + "name": "UNSAFE_CHANGE_DEPOSITED_VALIDATORS_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -438,19 +902,29 @@ { "constant": true, "inputs": [], - "name": "PUBKEY_LENGTH", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "getBeaconStat", + "outputs": [ + { + "name": "depositedValidators", + "type": "uint256" + }, + { + "name": "beaconValidators", + "type": "uint256" + }, + { + "name": "beaconBalance", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [ - { "name": "_amount", "type": "uint256" }, - { "name": "_pubkeyHash", "type": "bytes32" } - ], - "name": "withdraw", + "inputs": [], + "name": "removeStakingLimit", "outputs": [], "payable": false, "stateMutability": "nonpayable", @@ -459,11 +933,50 @@ { "constant": false, "inputs": [ - { "name": "_recipient", "type": "address" }, - { "name": "_amount", "type": "uint256" } + { + "name": "_reportTimestamp", + "type": "uint256" + }, + { + "name": "_timeElapsed", + "type": "uint256" + }, + { + "name": "_clValidators", + "type": "uint256" + }, + { + "name": "_clBalance", + "type": "uint256" + }, + { + "name": "_withdrawalVaultBalance", + "type": "uint256" + }, + { + "name": "_elRewardsVaultBalance", + "type": "uint256" + }, + { + "name": "_sharesRequestedToBurn", + "type": "uint256" + }, + { + "name": "_withdrawalFinalizationBatches", + "type": "uint256[]" + }, + { + "name": "_simulatedShareRate", + "type": "uint256" + } + ], + "name": "handleOracleReport", + "outputs": [ + { + "name": "postRebaseAmounts", + "type": "uint256[4]" + } ], - "name": "transfer", - "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -471,8 +984,13 @@ { "constant": true, "inputs": [], - "name": "getDepositContract", - "outputs": [{ "name": "", "type": "address" }], + "name": "getFee", + "outputs": [ + { + "name": "totalFee", + "type": "uint16" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -480,11 +998,12 @@ { "constant": true, "inputs": [], - "name": "getBeaconStat", + "name": "kernel", "outputs": [ - { "name": "depositedValidators", "type": "uint256" }, - { "name": "beaconValidators", "type": "uint256" }, - { "name": "beaconBalance", "type": "uint256" } + { + "name": "", + "type": "address" + } ], "payable": false, "stateMutability": "view", @@ -493,16 +1012,50 @@ { "constant": true, "inputs": [], - "name": "BURN_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "getTotalShares", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [{ "name": "_insuranceFund", "type": "address" }], - "name": "setInsuranceFund", + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_deadline", + "type": "uint256" + }, + { + "name": "_v", + "type": "uint8" + }, + { + "name": "_r", + "type": "bytes32" + }, + { + "name": "_s", + "type": "bytes32" + } + ], + "name": "permit", "outputs": [], "payable": false, "stateMutability": "nonpayable", @@ -510,9 +1063,23 @@ }, { "constant": true, - "inputs": [], - "name": "getFee", - "outputs": [{ "name": "feeBasisPoints", "type": "uint16" }], + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -520,8 +1087,13 @@ { "constant": true, "inputs": [], - "name": "SET_INSURANCE_FUND", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "isPetrified", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -529,8 +1101,13 @@ { "constant": true, "inputs": [], - "name": "kernel", - "outputs": [{ "name": "", "type": "address" }], + "name": "getLidoLocator", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -538,20 +1115,27 @@ { "constant": true, "inputs": [], - "name": "getTotalShares", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "canDeposit", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [ - { "name": "_owner", "type": "address" }, - { "name": "_spender", "type": "address" } + "inputs": [], + "name": "STAKING_PAUSE_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } ], - "name": "allowance", - "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" @@ -559,166 +1143,458 @@ { "constant": true, "inputs": [], - "name": "isPetrified", - "outputs": [{ "name": "", "type": "bool" }], + "name": "getDepositableEther", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [{ "name": "_withdrawalCredentials", "type": "bytes32" }], - "name": "setWithdrawalCredentials", - "outputs": [], + "constant": true, + "inputs": [ + { + "name": "_account", + "type": "address" + } + ], + "name": "sharesOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], - "name": "depositBufferedEther", + "name": "pauseStaking", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, - "inputs": [ - { "name": "_account", "type": "address" }, - { "name": "_sharesAmount", "type": "uint256" } + "constant": true, + "inputs": [], + "name": "getTotalELRewardsCollected", + "outputs": [ + { + "name": "", + "type": "uint256" + } ], - "name": "burnShares", - "outputs": [{ "name": "newTotalShares", "type": "uint256" }], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [{ "name": "_treasury", "type": "address" }], - "name": "setTreasury", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" + "payable": true, + "stateMutability": "payable", + "type": "fallback" }, { - "constant": false, + "anonymous": false, + "inputs": [], + "name": "StakingPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "StakingResumed", + "type": "event" + }, + { + "anonymous": false, "inputs": [ - { "name": "_beaconValidators", "type": "uint256" }, - { "name": "_beaconBalance", "type": "uint256" } + { + "indexed": false, + "name": "maxStakeLimit", + "type": "uint256" + }, + { + "indexed": false, + "name": "stakeLimitIncreasePerBlock", + "type": "uint256" + } ], - "name": "pushBeacon", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" + "name": "StakingLimitSet", + "type": "event" }, { - "constant": true, - "inputs": [{ "name": "_account", "type": "address" }], - "name": "sharesOf", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" + "anonymous": false, + "inputs": [], + "name": "StakingLimitRemoved", + "type": "event" }, - { "payable": true, "stateMutability": "payable", "type": "fallback" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "executor", "type": "address" }, - { "indexed": false, "name": "script", "type": "bytes" }, - { "indexed": false, "name": "input", "type": "bytes" }, - { "indexed": false, "name": "returnData", "type": "bytes" } + { + "indexed": true, + "name": "reportTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "name": "preCLValidators", + "type": "uint256" + }, + { + "indexed": false, + "name": "postCLValidators", + "type": "uint256" + } ], - "name": "ScriptResult", + "name": "CLValidatorsUpdated", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "vault", "type": "address" }, - { "indexed": true, "name": "token", "type": "address" }, - { "indexed": false, "name": "amount", "type": "uint256" } + { + "indexed": false, + "name": "depositedValidators", + "type": "uint256" + } ], - "name": "RecoverToVault", + "name": "DepositedValidatorsChanged", "type": "event" }, - { "anonymous": false, "inputs": [], "name": "Stopped", "type": "event" }, - { "anonymous": false, "inputs": [], "name": "Resumed", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "from", "type": "address" }, - { "indexed": true, "name": "to", "type": "address" }, - { "indexed": false, "name": "value", "type": "uint256" } + { + "indexed": true, + "name": "reportTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "name": "preCLBalance", + "type": "uint256" + }, + { + "indexed": false, + "name": "postCLBalance", + "type": "uint256" + }, + { + "indexed": false, + "name": "withdrawalsWithdrawn", + "type": "uint256" + }, + { + "indexed": false, + "name": "executionLayerRewardsWithdrawn", + "type": "uint256" + }, + { + "indexed": false, + "name": "postBufferedEther", + "type": "uint256" + } ], - "name": "Transfer", + "name": "ETHDistributed", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "owner", "type": "address" }, - { "indexed": true, "name": "spender", "type": "address" }, - { "indexed": false, "name": "value", "type": "uint256" } + { + "indexed": true, + "name": "reportTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "name": "timeElapsed", + "type": "uint256" + }, + { + "indexed": false, + "name": "preTotalShares", + "type": "uint256" + }, + { + "indexed": false, + "name": "preTotalEther", + "type": "uint256" + }, + { + "indexed": false, + "name": "postTotalShares", + "type": "uint256" + }, + { + "indexed": false, + "name": "postTotalEther", + "type": "uint256" + }, + { + "indexed": false, + "name": "sharesMintedAsFees", + "type": "uint256" + } ], - "name": "Approval", + "name": "TokenRebased", "type": "event" }, { "anonymous": false, - "inputs": [{ "indexed": false, "name": "feeBasisPoints", "type": "uint16" }], - "name": "FeeSet", + "inputs": [ + { + "indexed": false, + "name": "lidoLocator", + "type": "address" + } + ], + "name": "LidoLocatorSet", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": false, "name": "treasuryFeeBasisPoints", "type": "uint16" }, - { "indexed": false, "name": "insuranceFeeBasisPoints", "type": "uint16" }, - { "indexed": false, "name": "operatorsFeeBasisPoints", "type": "uint16" } + { + "indexed": false, + "name": "amount", + "type": "uint256" + } ], - "name": "FeeDistributionSet", + "name": "ELRewardsReceived", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": false, "name": "withdrawalCredentials", "type": "bytes32" } + { + "indexed": false, + "name": "amount", + "type": "uint256" + } ], - "name": "WithdrawalCredentialsSet", + "name": "WithdrawalsReceived", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "sender", "type": "address" }, - { "indexed": false, "name": "amount", "type": "uint256" }, - { "indexed": false, "name": "referral", "type": "address" } + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "name": "referral", + "type": "address" + } ], "name": "Submitted", "type": "event" }, { "anonymous": false, - "inputs": [{ "indexed": false, "name": "amount", "type": "uint256" }], + "inputs": [ + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], "name": "Unbuffered", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "sender", "type": "address" }, - { "indexed": false, "name": "tokenAmount", "type": "uint256" }, - { "indexed": false, "name": "sentFromBuffer", "type": "uint256" }, - { "indexed": true, "name": "pubkeyHash", "type": "bytes32" }, - { "indexed": false, "name": "etherAmount", "type": "uint256" } + { + "indexed": true, + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "name": "script", + "type": "bytes" + }, + { + "indexed": false, + "name": "input", + "type": "bytes" + }, + { + "indexed": false, + "name": "returnData", + "type": "bytes" + } + ], + "name": "ScriptResult", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "RecoverToVault", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "eip712StETH", + "type": "address" + } + ], + "name": "EIP712StETHInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "sharesValue", + "type": "uint256" + } + ], + "name": "TransferShares", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "account", + "type": "address" + }, + { + "indexed": false, + "name": "preRebaseTokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "postRebaseTokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "sharesAmount", + "type": "uint256" + } + ], + "name": "SharesBurnt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Stopped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Resumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "version", + "type": "uint256" + } ], - "name": "Withdrawal", + "name": "ContractVersionSet", "type": "event" } ] diff --git a/interfaces/LidoLocator.json b/interfaces/LidoLocator.json new file mode 100644 index 00000000..f2145f2d --- /dev/null +++ b/interfaces/LidoLocator.json @@ -0,0 +1 @@ +[{"inputs":[{"components":[{"internalType":"address","name":"accountingOracle","type":"address"},{"internalType":"address","name":"depositSecurityModule","type":"address"},{"internalType":"address","name":"elRewardsVault","type":"address"},{"internalType":"address","name":"legacyOracle","type":"address"},{"internalType":"address","name":"lido","type":"address"},{"internalType":"address","name":"oracleReportSanityChecker","type":"address"},{"internalType":"address","name":"postTokenRebaseReceiver","type":"address"},{"internalType":"address","name":"burner","type":"address"},{"internalType":"address","name":"stakingRouter","type":"address"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"validatorsExitBusOracle","type":"address"},{"internalType":"address","name":"withdrawalQueue","type":"address"},{"internalType":"address","name":"withdrawalVault","type":"address"},{"internalType":"address","name":"oracleDaemonConfig","type":"address"}],"internalType":"struct LidoLocator.Config","name":"_config","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"accountingOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coreComponents","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositSecurityModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"elRewardsVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legacyOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lido","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleDaemonConfig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleReportComponentsForLido","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleReportSanityChecker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"postTokenRebaseReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorsExitBusOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalQueue","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/interfaces/NodeOperatorsRegistry.json b/interfaces/NodeOperatorsRegistry.json index 449a7266..c4d45bb4 100644 --- a/interfaces/NodeOperatorsRegistry.json +++ b/interfaces/NodeOperatorsRegistry.json @@ -3,7 +3,12 @@ "constant": true, "inputs": [], "name": "hasInitialized", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -11,10 +16,22 @@ { "constant": false, "inputs": [ - { "name": "_operator_id", "type": "uint256" }, - { "name": "_quantity", "type": "uint256" }, - { "name": "_pubkeys", "type": "bytes" }, - { "name": "_signatures", "type": "bytes" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } ], "name": "addSigningKeys", "outputs": [], @@ -24,29 +41,51 @@ }, { "constant": true, - "inputs": [{ "name": "_script", "type": "bytes" }], - "name": "getEVMScriptExecutor", - "outputs": [{ "name": "", "type": "address" }], + "inputs": [], + "name": "getType", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [], - "name": "getRecoveryVault", - "outputs": [{ "name": "", "type": "address" }], + "inputs": [ + { + "name": "_script", + "type": "bytes" + } + ], + "name": "getEVMScriptExecutor", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [{ "name": "_numKeys", "type": "uint256" }], - "name": "assignNextSigningKeys", + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "clearNodeOperatorPenalty", "outputs": [ - { "name": "pubkeys", "type": "bytes" }, - { "name": "signatures", "type": "bytes" } + { + "name": "", + "type": "bool" + } ], "payable": false, "stateMutability": "nonpayable", @@ -55,17 +94,71 @@ { "constant": true, "inputs": [], - "name": "SIGNATURE_LENGTH", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "getRecoveryVault", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [], - "name": "SET_NODE_OPERATOR_ADDRESS_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "inputs": [ + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getNodeOperatorIds", + "outputs": [ + { + "name": "nodeOperatorIds", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getSigningKeys", + "outputs": [ + { + "name": "pubkeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + }, + { + "name": "used", + "type": "bool[]" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -73,9 +166,18 @@ { "constant": false, "inputs": [ - { "name": "_operator_id", "type": "uint256" }, - { "name": "_index", "type": "uint256" }, - { "name": "_amount", "type": "uint256" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } ], "name": "removeSigningKeysOperatorBH", "outputs": [], @@ -83,11 +185,36 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorIsActive", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": false, "inputs": [ - { "name": "_id", "type": "uint256" }, - { "name": "_name", "type": "string" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_name", + "type": "string" + } ], "name": "setNodeOperatorName", "outputs": [], @@ -97,11 +224,26 @@ }, { "constant": true, - "inputs": [{ "name": "_totalRewardShares", "type": "uint256" }], + "inputs": [ + { + "name": "_totalRewardShares", + "type": "uint256" + } + ], "name": "getRewardsDistribution", "outputs": [ - { "name": "recipients", "type": "address[]" }, - { "name": "shares", "type": "uint256[]" } + { + "name": "recipients", + "type": "address[]" + }, + { + "name": "shares", + "type": "uint256[]" + }, + { + "name": "penalized", + "type": "bool[]" + } ], "payable": false, "stateMutability": "view", @@ -110,10 +252,52 @@ { "constant": false, "inputs": [ - { "name": "_id", "type": "uint256" }, - { "name": "_active", "type": "bool" } + { + "name": "_indexFrom", + "type": "uint256" + }, + { + "name": "_indexTo", + "type": "uint256" + } + ], + "name": "invalidateReadyToDepositKeysRange", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_delay", + "type": "uint256" + } ], - "name": "setNodeOperatorActive", + "name": "setStuckPenaltyDelay", "outputs": [], "payable": false, "stateMutability": "nonpayable", @@ -122,8 +306,13 @@ { "constant": true, "inputs": [], - "name": "SET_NODE_OPERATOR_NAME_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "getStuckPenaltyDelay", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -131,8 +320,14 @@ { "constant": false, "inputs": [ - { "name": "_operator_id", "type": "uint256" }, - { "name": "_index", "type": "uint256" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } ], "name": "removeSigningKey", "outputs": [], @@ -143,9 +338,18 @@ { "constant": false, "inputs": [ - { "name": "_operator_id", "type": "uint256" }, - { "name": "_index", "type": "uint256" }, - { "name": "_amount", "type": "uint256" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } ], "name": "removeSigningKeys", "outputs": [], @@ -155,18 +359,66 @@ }, { "constant": true, - "inputs": [], - "name": "ADD_NODE_OPERATOR_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenalized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "deactivateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, - "inputs": [{ "name": "token", "type": "address" }], + "inputs": [ + { + "name": "token", + "type": "address" + } + ], "name": "allowRecoverability", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "STAKING_ROUTER_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -174,10 +426,22 @@ { "constant": false, "inputs": [ - { "name": "_operator_id", "type": "uint256" }, - { "name": "_quantity", "type": "uint256" }, - { "name": "_pubkeys", "type": "bytes" }, - { "name": "_signatures", "type": "bytes" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } ], "name": "addSigningKeysOperatorBH", "outputs": [], @@ -189,7 +453,12 @@ "constant": true, "inputs": [], "name": "appId", - "outputs": [{ "name": "", "type": "bytes32" }], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -198,7 +467,12 @@ "constant": true, "inputs": [], "name": "getActiveNodeOperatorsCount", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -206,38 +480,135 @@ { "constant": false, "inputs": [ - { "name": "_name", "type": "string" }, - { "name": "_rewardAddress", "type": "address" } + { + "name": "_name", + "type": "string" + }, + { + "name": "_rewardAddress", + "type": "address" + } ], "name": "addNodeOperator", - "outputs": [{ "name": "id", "type": "uint256" }], + "outputs": [ + { + "name": "id", + "type": "uint256" + } + ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], "name": "getInitializationBlock", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [{ "name": "_operator_id", "type": "uint256" }], + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], "name": "getUnusedSigningKeyCount", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "onRewardsMinted", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MANAGE_NODE_OPERATOR_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [], + "name": "onWithdrawalCredentialsChanged", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ - { "name": "_id", "type": "uint256" }, - { "name": "_rewardAddress", "type": "address" } + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "activateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_rewardAddress", + "type": "address" + } ], "name": "setNodeOperatorRewardAddress", "outputs": [], @@ -248,18 +619,89 @@ { "constant": true, "inputs": [ - { "name": "_id", "type": "uint256" }, - { "name": "_fullInfo", "type": "bool" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fullInfo", + "type": "bool" + } ], "name": "getNodeOperator", "outputs": [ - { "name": "active", "type": "bool" }, - { "name": "name", "type": "string" }, - { "name": "rewardAddress", "type": "address" }, - { "name": "stakingLimit", "type": "uint64" }, - { "name": "stoppedValidators", "type": "uint64" }, - { "name": "totalSigningKeys", "type": "uint64" }, - { "name": "usedSigningKeys", "type": "uint64" } + { + "name": "active", + "type": "bool" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "rewardAddress", + "type": "address" + }, + { + "name": "totalVettedValidators", + "type": "uint64" + }, + { + "name": "totalExitedValidators", + "type": "uint64" + }, + { + "name": "totalAddedValidators", + "type": "uint64" + }, + { + "name": "totalDepositedValidators", + "type": "uint64" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStakingModuleSummary", + "outputs": [ + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } ], "payable": false, "stateMutability": "view", @@ -267,7 +709,48 @@ }, { "constant": false, - "inputs": [{ "name": "_token", "type": "address" }], + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_exitedValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateExitedValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_stuckValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateStuckValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], "name": "transferToVault", "outputs": [], "payable": false, @@ -277,30 +760,58 @@ { "constant": true, "inputs": [ - { "name": "_sender", "type": "address" }, - { "name": "_role", "type": "bytes32" }, - { "name": "_params", "type": "uint256[]" } + { + "name": "_sender", + "type": "address" + }, + { + "name": "_role", + "type": "bytes32" + }, + { + "name": "_params", + "type": "uint256[]" + } ], "name": "canPerform", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, - "inputs": [], - "name": "getEVMScriptRegistry", - "outputs": [{ "name": "", "type": "address" }], + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_refundedValidatorsCount", + "type": "uint256" + } + ], + "name": "updateRefundedValidatorsCount", + "outputs": [], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], - "name": "PUBKEY_LENGTH", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "getEVMScriptRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -309,7 +820,12 @@ "constant": true, "inputs": [], "name": "getNodeOperatorsCount", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -317,8 +833,36 @@ { "constant": false, "inputs": [ - { "name": "_id", "type": "uint256" }, - { "name": "_stakingLimit", "type": "uint64" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_isTargetLimitActive", + "type": "bool" + }, + { + "name": "_targetLimit", + "type": "uint256" + } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_vettedSigningKeysCount", + "type": "uint64" + } ], "name": "setNodeOperatorStakingLimit", "outputs": [], @@ -329,36 +873,118 @@ { "constant": true, "inputs": [ - { "name": "_operator_id", "type": "uint256" }, - { "name": "_index", "type": "uint256" } + { + "name": "_nodeOperatorId", + "type": "uint256" + } ], - "name": "getSigningKey", + "name": "getNodeOperatorSummary", "outputs": [ - { "name": "key", "type": "bytes" }, - { "name": "depositSignature", "type": "bytes" }, - { "name": "used", "type": "bool" } + { + "name": "isTargetLimitActive", + "type": "bool" + }, + { + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } ], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, + "constant": true, "inputs": [ - { "name": "_id", "type": "uint256" }, - { "name": "_stoppedIncrement", "type": "uint64" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "getSigningKey", + "outputs": [ + { + "name": "key", + "type": "bytes" + }, + { + "name": "depositSignature", + "type": "bytes" + }, + { + "name": "used", + "type": "bool" + } ], - "name": "reportStoppedValidators", - "outputs": [], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATOR_NAME_LENGTH", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", "type": "function" }, { "constant": false, - "inputs": [{ "name": "_lido", "type": "address" }], - "name": "initialize", - "outputs": [], + "inputs": [ + { + "name": "_depositsCount", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "obtainDepositData", + "outputs": [ + { + "name": "publicKeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + } + ], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -366,8 +992,13 @@ { "constant": true, "inputs": [], - "name": "REPORT_STOPPED_VALIDATORS_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "getKeysOpIndex", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -375,8 +1006,13 @@ { "constant": true, "inputs": [], - "name": "getKeysOpIndex", - "outputs": [{ "name": "", "type": "uint256" }], + "name": "getNonce", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -385,7 +1021,12 @@ "constant": true, "inputs": [], "name": "kernel", - "outputs": [{ "name": "", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -393,8 +1034,13 @@ { "constant": true, "inputs": [], - "name": "SET_NODE_OPERATOR_ACTIVE_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "name": "getLocator", + "outputs": [ + { + "name": "", + "type": "address" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -403,16 +1049,31 @@ "constant": true, "inputs": [], "name": "SET_NODE_OPERATOR_LIMIT_ROLE", - "outputs": [{ "name": "", "type": "bytes32" }], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, - "inputs": [{ "name": "_operator_id", "type": "uint256" }], + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], "name": "getTotalSigningKeyCount", - "outputs": [{ "name": "", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -421,7 +1082,49 @@ "constant": true, "inputs": [], "name": "isPetrified", - "outputs": [{ "name": "", "type": "bool" }], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_STUCK_PENALTY_DELAY", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "onExitedAndStuckValidatorsCountsUpdated", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATORS_COUNT", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], "payable": false, "stateMutability": "view", "type": "function" @@ -429,8 +1132,14 @@ { "constant": false, "inputs": [ - { "name": "_operator_id", "type": "uint256" }, - { "name": "_index", "type": "uint256" } + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } ], "name": "removeSigningKeyOperatorBH", "outputs": [], @@ -438,132 +1147,421 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_exitedValidatorsCount", + "type": "uint256" + }, + { + "name": "_stuckValidatorsCount", + "type": "uint256" + } + ], + "name": "unsafeUpdateValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": true, "inputs": [], "name": "MANAGE_SIGNING_KEYS", - "outputs": [{ "name": "", "type": "bytes32" }], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [], - "name": "trimUnusedKeys", - "outputs": [], + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenaltyCleared", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "executor", "type": "address" }, - { "indexed": false, "name": "script", "type": "bytes" }, - { "indexed": false, "name": "input", "type": "bytes" }, - { "indexed": false, "name": "returnData", "type": "bytes" } + { + "indexed": false, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "stakingLimit", + "type": "uint64" + } ], - "name": "ScriptResult", + "name": "NodeOperatorAdded", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "vault", "type": "address" }, - { "indexed": true, "name": "token", "type": "address" }, - { "indexed": false, "name": "amount", "type": "uint256" } + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "active", + "type": "bool" + } ], - "name": "RecoverToVault", + "name": "NodeOperatorActiveSet", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": false, "name": "id", "type": "uint256" }, - { "indexed": false, "name": "name", "type": "string" }, - { "indexed": false, "name": "rewardAddress", "type": "address" }, - { "indexed": false, "name": "stakingLimit", "type": "uint64" } + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + } ], - "name": "NodeOperatorAdded", + "name": "NodeOperatorNameSet", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "id", "type": "uint256" }, - { "indexed": false, "name": "active", "type": "bool" } + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + } ], - "name": "NodeOperatorActiveSet", + "name": "NodeOperatorRewardAddressSet", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "id", "type": "uint256" }, - { "indexed": false, "name": "name", "type": "string" } + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalKeysTrimmed", + "type": "uint64" + } ], - "name": "NodeOperatorNameSet", + "name": "NodeOperatorTotalKeysTrimmed", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "id", "type": "uint256" }, - { "indexed": false, "name": "rewardAddress", "type": "address" } + { + "indexed": false, + "name": "keysOpIndex", + "type": "uint256" + } ], - "name": "NodeOperatorRewardAddressSet", + "name": "KeysOpIndexSet", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "id", "type": "uint256" }, - { "indexed": false, "name": "stakingLimit", "type": "uint64" } + { + "indexed": false, + "name": "moduleType", + "type": "bytes32" + } ], - "name": "NodeOperatorStakingLimitSet", + "name": "StakingModuleTypeSet", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "id", "type": "uint256" }, - { "indexed": false, "name": "totalStopped", "type": "uint64" } + { + "indexed": true, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesAmount", + "type": "uint256" + } ], - "name": "NodeOperatorTotalStoppedValidatorsReported", + "name": "RewardsDistributed", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "id", "type": "uint256" }, - { "indexed": false, "name": "totalKeysTrimmed", "type": "uint64" } + { + "indexed": false, + "name": "locatorAddress", + "type": "address" + } ], - "name": "NodeOperatorTotalKeysTrimmed", + "name": "LocatorContractSet", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "operatorId", "type": "uint256" }, - { "indexed": false, "name": "pubkey", "type": "bytes" } + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "approvedValidatorsCount", + "type": "uint256" + } ], - "name": "SigningKeyAdded", + "name": "VettedSigningKeysCountChanged", "type": "event" }, { "anonymous": false, "inputs": [ - { "indexed": true, "name": "operatorId", "type": "uint256" }, - { "indexed": false, "name": "pubkey", "type": "bytes" } + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "depositedValidatorsCount", + "type": "uint256" + } ], - "name": "SigningKeyRemoved", + "name": "DepositedSigningKeysCountChanged", "type": "event" }, { "anonymous": false, - "inputs": [{ "indexed": false, "name": "keysOpIndex", "type": "uint256" }], - "name": "KeysOpIndexSet", + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "exitedValidatorsCount", + "type": "uint256" + } + ], + "name": "ExitedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalValidatorsCount", + "type": "uint256" + } + ], + "name": "TotalSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "nonce", + "type": "uint256" + } + ], + "name": "NonceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "StuckPenaltyDelayChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + } + ], + "name": "StuckPenaltyStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "targetValidatorsCount", + "type": "uint256" + } + ], + "name": "TargetValidatorsCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "recipientAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesPenalizedAmount", + "type": "uint256" + } + ], + "name": "NodeOperatorPenalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "name": "script", + "type": "bytes" + }, + { + "indexed": false, + "name": "input", + "type": "bytes" + }, + { + "indexed": false, + "name": "returnData", + "type": "bytes" + } + ], + "name": "ScriptResult", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "RecoverToVault", "type": "event" } ] diff --git a/interfaces/Oracle.json b/interfaces/Oracle.json deleted file mode 100644 index a7c45e75..00000000 --- a/interfaces/Oracle.json +++ /dev/null @@ -1,525 +0,0 @@ -[ - { - "constant": true, - "inputs": [], - "name": "getCurrentOraclesReportStatus", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "_value", "type": "uint256" }], - "name": "setAllowedBeaconBalanceAnnualRelativeIncrease", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "hasInitialized", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getVersion", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [{ "name": "_script", "type": "bytes" }], - "name": "getEVMScriptExecutor", - "outputs": [{ "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MANAGE_QUORUM", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "_epochId", "type": "uint256" }, - { "name": "_beaconBalance", "type": "uint64" }, - { "name": "_beaconValidators", "type": "uint32" } - ], - "name": "reportBeacon", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getRecoveryVault", - "outputs": [{ "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getAllowedBeaconBalanceAnnualRelativeIncrease", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getAllowedBeaconBalanceRelativeDecrease", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getExpectedEpochId", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getLastCompletedReportDelta", - "outputs": [ - { "name": "postTotalPooledEther", "type": "uint256" }, - { "name": "preTotalPooledEther", "type": "uint256" }, - { "name": "timeElapsed", "type": "uint256" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getLido", - "outputs": [{ "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "SET_BEACON_REPORT_RECEIVER", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MANAGE_MEMBERS", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getCurrentFrame", - "outputs": [ - { "name": "frameEpochId", "type": "uint256" }, - { "name": "frameStartTime", "type": "uint256" }, - { "name": "frameEndTime", "type": "uint256" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [{ "name": "token", "type": "address" }], - "name": "allowRecoverability", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [{ "name": "_index", "type": "uint256" }], - "name": "getCurrentReportVariant", - "outputs": [ - { "name": "beaconBalance", "type": "uint64" }, - { "name": "beaconValidators", "type": "uint32" }, - { "name": "count", "type": "uint16" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "appId", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getLastCompletedEpochId", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getInitializationBlock", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "_allowedBeaconBalanceAnnualRelativeIncrease", "type": "uint256" }, - { "name": "_allowedBeaconBalanceRelativeDecrease", "type": "uint256" } - ], - "name": "initialize_v2", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "_addr", "type": "address" }], - "name": "setBeaconReportReceiver", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "_token", "type": "address" }], - "name": "transferToVault", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "SET_BEACON_SPEC", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "name": "_sender", "type": "address" }, - { "name": "_role", "type": "bytes32" }, - { "name": "_params", "type": "uint256[]" } - ], - "name": "canPerform", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getCurrentEpochId", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getEVMScriptRegistry", - "outputs": [{ "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "_member", "type": "address" }], - "name": "addOracleMember", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getBeaconReportReceiver", - "outputs": [{ "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "SET_REPORT_BOUNDARIES", - "outputs": [{ "name": "", "type": "bytes32" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "_quorum", "type": "uint256" }], - "name": "setQuorum", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getQuorum", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "kernel", - "outputs": [{ "name": "", "type": "address" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getOracleMembers", - "outputs": [{ "name": "", "type": "address[]" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "isPetrified", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "_value", "type": "uint256" }], - "name": "setAllowedBeaconBalanceRelativeDecrease", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getBeaconSpec", - "outputs": [ - { "name": "epochsPerFrame", "type": "uint64" }, - { "name": "slotsPerEpoch", "type": "uint64" }, - { "name": "secondsPerSlot", "type": "uint64" }, - { "name": "genesisTime", "type": "uint64" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "_epochsPerFrame", "type": "uint64" }, - { "name": "_slotsPerEpoch", "type": "uint64" }, - { "name": "_secondsPerSlot", "type": "uint64" }, - { "name": "_genesisTime", "type": "uint64" } - ], - "name": "setBeaconSpec", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_MEMBERS", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getCurrentReportVariantsSize", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "_member", "type": "address" }], - "name": "removeOracleMember", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "executor", "type": "address" }, - { "indexed": false, "name": "script", "type": "bytes" }, - { "indexed": false, "name": "input", "type": "bytes" }, - { "indexed": false, "name": "returnData", "type": "bytes" } - ], - "name": "ScriptResult", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "vault", "type": "address" }, - { "indexed": true, "name": "token", "type": "address" }, - { "indexed": false, "name": "amount", "type": "uint256" } - ], - "name": "RecoverToVault", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "value", "type": "uint256" }], - "name": "AllowedBeaconBalanceAnnualRelativeIncreaseSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "value", "type": "uint256" }], - "name": "AllowedBeaconBalanceRelativeDecreaseSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "callback", "type": "address" }], - "name": "BeaconReportReceiverSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "member", "type": "address" }], - "name": "MemberAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "member", "type": "address" }], - "name": "MemberRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "quorum", "type": "uint256" }], - "name": "QuorumChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "epochId", "type": "uint256" }], - "name": "ExpectedEpochIdUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "name": "epochsPerFrame", "type": "uint64" }, - { "indexed": false, "name": "slotsPerEpoch", "type": "uint64" }, - { "indexed": false, "name": "secondsPerSlot", "type": "uint64" }, - { "indexed": false, "name": "genesisTime", "type": "uint64" } - ], - "name": "BeaconSpecSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "name": "epochId", "type": "uint256" }, - { "indexed": false, "name": "beaconBalance", "type": "uint128" }, - { "indexed": false, "name": "beaconValidators", "type": "uint128" }, - { "indexed": false, "name": "caller", "type": "address" } - ], - "name": "BeaconReported", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "name": "epochId", "type": "uint256" }, - { "indexed": false, "name": "beaconBalance", "type": "uint128" }, - { "indexed": false, "name": "beaconValidators", "type": "uint128" } - ], - "name": "Completed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "name": "postTotalPooledEther", "type": "uint256" }, - { "indexed": false, "name": "preTotalPooledEther", "type": "uint256" }, - { "indexed": false, "name": "timeElapsed", "type": "uint256" }, - { "indexed": false, "name": "totalShares", "type": "uint256" } - ], - "name": "PostTotalShares", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "name": "version", "type": "uint256" }], - "name": "ContractVersionSet", - "type": "event" - } -] diff --git a/interfaces/StakingRouter.json b/interfaces/StakingRouter.json new file mode 100644 index 00000000..c72053cd --- /dev/null +++ b/interfaces/StakingRouter.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_depositContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AppAuthLidoFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"firstArrayLength","type":"uint256"},{"internalType":"uint256","name":"secondArrayLength","type":"uint256"}],"name":"ArraysLengthMismatch","type":"error"},{"inputs":[],"name":"DepositContractZeroAddress","type":"error"},{"inputs":[],"name":"DirectETHTransfer","type":"error"},{"inputs":[],"name":"EmptyWithdrawalsCredentials","type":"error"},{"inputs":[],"name":"ExitedValidatorsCountCannotDecrease","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[{"internalType":"uint256","name":"etherValue","type":"uint256"},{"internalType":"uint256","name":"depositsCount","type":"uint256"}],"name":"InvalidDepositsValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidPublicKeysBatchLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"InvalidReportData","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidSignaturesBatchLength","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"reportedExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"depositedValidatorsCount","type":"uint256"}],"name":"ReportedExitedValidatorsExceedDeposited","type":"error"},{"inputs":[],"name":"StakingModuleAddressExists","type":"error"},{"inputs":[],"name":"StakingModuleNotActive","type":"error"},{"inputs":[],"name":"StakingModuleNotPaused","type":"error"},{"inputs":[],"name":"StakingModuleStatusTheSame","type":"error"},{"inputs":[],"name":"StakingModuleUnregistered","type":"error"},{"inputs":[],"name":"StakingModuleWrongName","type":"error"},{"inputs":[],"name":"StakingModulesLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpStuckValidatorsCount","type":"uint256"}],"name":"UnexpectedCurrentValidatorsCount","type":"error"},{"inputs":[],"name":"UnrecoverableModuleError","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ValueOver100Percent","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"ExitedAndStuckValidatorsCountsUpdateFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"RewardsMintedReportFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"address","name":"stakingModule","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"createdBy","type":"address"}],"name":"StakingModuleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unreportedExitedValidatorsCount","type":"uint256"}],"name":"StakingModuleExitedValidatorsIncompleteReporting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakingModuleFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleFeesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"enum StakingRouter.StakingModuleStatus","name":"status","type":"uint8"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleStatusSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"targetShare","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleTargetShareSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakingRouterETHDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"WithdrawalCredentialsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"WithdrawalsCredentialsChangeFailed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_PRECISION_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_WITHDRAWAL_CREDENTIALS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULES_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULE_NAME_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_REWARDS_MINTED_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_MANAGE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_RESUME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNSAFE_SET_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_stakingModuleAddress","type":"address"},{"internalType":"uint256","name":"_targetShare","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"addStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_depositCalldata","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getAllNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"}],"name":"getDepositsAllocation","outputs":[{"internalType":"uint256","name":"allocated","type":"uint256"},{"internalType":"uint256[]","name":"allocations","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLido","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256[]","name":"_nodeOperatorIds","type":"uint256[]"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistribution","outputs":[{"internalType":"uint96","name":"modulesFee","type":"uint96"},{"internalType":"uint96","name":"treasuryFee","type":"uint96"},{"internalType":"uint256","name":"basePrecision","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistributionE4Precision","outputs":[{"internalType":"uint16","name":"modulesFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModule","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleActiveValidatorsCount","outputs":[{"internalType":"uint256","name":"activeValidatorsCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"}],"name":"getStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModuleIds","outputs":[{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsDepositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsStopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleLastDepositBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_maxDepositsValue","type":"uint256"}],"name":"getStakingModuleMaxDepositsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleStatus","outputs":[{"internalType":"enum StakingRouter.StakingModuleStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleSummary","outputs":[{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModules","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule[]","name":"res","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModulesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingRewardsDistribution","outputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"},{"internalType":"uint96[]","name":"stakingModuleFees","type":"uint96[]"},{"internalType":"uint96","name":"totalFee","type":"uint96"},{"internalType":"uint256","name":"precisionPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalFeeE4Precision","outputs":[{"internalType":"uint16","name":"totalFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"hasStakingModule","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_lido","type":"address"},{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onValidatorsCountsByNodeOperatorReportingFinished","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"pauseStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_totalShares","type":"uint256[]"}],"name":"reportRewardsMinted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_exitedValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleExitedValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_stuckValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleStuckValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"resumeStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"enum StakingRouter.StakingModuleStatus","name":"_status","type":"uint8"}],"name":"setStakingModuleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"setWithdrawalCredentials","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"bool","name":"_triggerUpdateFinish","type":"bool"},{"components":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorStuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorStuckValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.ValidatorsCountsCorrection","name":"_correction","type":"tuple"}],"name":"unsafeSetExitedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_exitedValidatorsCounts","type":"uint256[]"}],"name":"updateExitedValidatorsCountByStakingModule","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"uint256","name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_targetShare","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"updateStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"bool","name":"_isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file diff --git a/network-config.yaml b/network-config.yaml new file mode 100644 index 00000000..ca571ae7 --- /dev/null +++ b/network-config.yaml @@ -0,0 +1,46 @@ +live: +- name: Ethereum + networks: + - chainid: 17000 + explorer: https://api-holesky.etherscan.io/api + host: $HOLESKY_RPC_URL + id: holesky + # New backward-compatible multicall contract. multicall2 is missing on Holesky. See https://github.com/mds1/multicall + multicall2: "0xcA11bde05977b3631167028862bE2a173976CA11" + name: Holesky (Infura) + provider: infura +development: + - cmd: ./ganache.sh + cmd_settings: + accounts: 10 + evm_version: istanbul + fork: mainnet + gas_limit: 30000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: mainnet-fork + name: Ganache-CLI (Mainnet Fork) + timeout: 120 + - cmd: ./ganache.sh + cmd_settings: + accounts: 10 + chain_id: 5 + fork: goerli + gas_limit: 30000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: goerli-fork + name: goerli-fork + - cmd: ./ganache.sh + cmd_settings: + accounts: 10 + chain_id: 17000 + fork: $HOLESKY_RPC_URL + gas_limit: 12000000 + mnemonic: brownie + port: 8545 + host: http://127.0.0.1 + id: holesky-fork + name: holesky-fork diff --git a/package-lock.json b/package-lock.json index d48c5673..df15f5cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { - "name": "easytrack", + "name": "easy-track", "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { + "name": "easy-track", "version": "1.0.0", - "hasInstallScript": true, - "license": "MIT", + "license": "GPL-3.0", "dependencies": { - "@openzeppelin/contracts": "^4.3.2", "ethlint": "^1.2.5", + "ganache": "^7.4.3", "husky": "^6.0.0", "prettier": "^2.3.0", "prettier-plugin-solidity": "^1.0.0-beta.10", @@ -20,16 +20,10 @@ "recursive-copy": "^2.0.13" } }, - "node_modules/@openzeppelin/contracts": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.4.0.tgz", - "integrity": "sha512-dlKiZmDvJnGRLHojrDoFZJmsQVeltVeoiRN7RK+cf2FmkhASDEblE0RiaYdxPNsUZa6mRG8393b9bfyp+V5IAw==", - "license": "MIT" - }, "node_modules/@solidity-parser/parser": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.0.tgz", - "integrity": "sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", + "integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==", "dependencies": { "antlr4ts": "^0.5.0-alpha.4" } @@ -42,7 +36,7 @@ "node_modules/ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", "dependencies": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", @@ -89,7 +83,7 @@ "node_modules/arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "integrity": "sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==", "dependencies": { "arr-flatten": "^1.0.1" }, @@ -108,7 +102,7 @@ "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "engines": { "node": ">=0.10.0" } @@ -132,7 +126,7 @@ "node_modules/array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true, "engines": { "node": ">=0.10.0" @@ -141,7 +135,7 @@ "node_modules/array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", "engines": { "node": ">=0.10.0" } @@ -157,13 +151,13 @@ "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "engines": { "node": ">=0.10.0" } @@ -209,7 +203,7 @@ "node_modules/base/node_modules/define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dependencies": { "is-descriptor": "^1.0.0" }, @@ -220,7 +214,7 @@ "node_modules/base/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -254,7 +248,7 @@ "node_modules/braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "integrity": "sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==", "dependencies": { "expand-range": "^1.8.1", "preserve": "^0.2.0", @@ -267,7 +261,7 @@ "node_modules/browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" + "integrity": "sha512-7Rfk377tpSM9TWBEeHs0FlDZGoAIei2V/4MdZJoFMBFAK6BqLpxAIUepGRHGdPFgGsLb02PXovC4qddyHvQqTg==" }, "node_modules/cache-base": { "version": "1.0.1", @@ -291,7 +285,7 @@ "node_modules/cache-base/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -299,7 +293,7 @@ "node_modules/camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", "engines": { "node": ">=4" } @@ -319,7 +313,7 @@ "node_modules/chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "integrity": "sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==", "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", "dependencies": { "anymatch": "^1.3.0", @@ -352,7 +346,7 @@ "node_modules/class-utils/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dependencies": { "is-descriptor": "^0.1.0" }, @@ -363,7 +357,7 @@ "node_modules/class-utils/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dependencies": { "kind-of": "^3.0.2" }, @@ -374,7 +368,7 @@ "node_modules/class-utils/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -406,7 +400,7 @@ "node_modules/class-utils/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -422,9 +416,9 @@ } }, "node_modules/cliui/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "engines": { "node": ">=4" } @@ -432,7 +426,7 @@ "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "engines": { "node": ">=4" } @@ -452,7 +446,7 @@ "node_modules/cliui/node_modules/strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dependencies": { "ansi-regex": "^3.0.0" }, @@ -463,7 +457,7 @@ "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -472,7 +466,7 @@ "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "engines": { "node": ">=0.10.0" } @@ -480,7 +474,7 @@ "node_modules/collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "dependencies": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -526,12 +520,12 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "engines": { "node": ">=0.10.0" } @@ -565,7 +559,7 @@ "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "engines": { "node": ">=0.10.0" } @@ -573,7 +567,7 @@ "node_modules/decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", "engines": { "node": ">=0.10" } @@ -593,25 +587,7 @@ "node_modules/define-property/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "dependencies": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -625,9 +601,9 @@ } }, "node_modules/emoji-regex": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.0.0.tgz", - "integrity": "sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw==" + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", + "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==" }, "node_modules/end-of-stream": { "version": "1.4.4", @@ -713,7 +689,7 @@ "node_modules/expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "integrity": "sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==", "dependencies": { "is-posix-bracket": "^0.1.0" }, @@ -724,7 +700,7 @@ "node_modules/expand-range": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "integrity": "sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==", "dependencies": { "fill-range": "^2.1.0" }, @@ -735,7 +711,7 @@ "node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -758,7 +734,7 @@ "node_modules/extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "integrity": "sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==", "dependencies": { "is-extglob": "^1.0.0" }, @@ -769,7 +745,7 @@ "node_modules/fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", @@ -785,7 +761,7 @@ "node_modules/filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "integrity": "sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ==", "engines": { "node": ">=0.10.0" } @@ -820,7 +796,7 @@ "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", "engines": { "node": ">=0.10.0" } @@ -828,7 +804,7 @@ "node_modules/for-own": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "integrity": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", "dependencies": { "for-in": "^1.0.1" }, @@ -839,7 +815,7 @@ "node_modules/fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", "dependencies": { "map-cache": "^0.2.2" }, @@ -850,7 +826,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "1.2.13", @@ -870,6 +846,504 @@ "node": ">= 4.0" } }, + "node_modules/ganache": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ganache/-/ganache-7.4.3.tgz", + "integrity": "sha512-RpEDUiCkqbouyE7+NMXG26ynZ+7sGiODU84Kz+FVoXUnQ4qQM4M8wif3Y4qUCt+D/eM1RVeGq0my62FPD6Y1KA==", + "bundleDependencies": [ + "@trufflesuite/bigint-buffer", + "emittery", + "keccak", + "leveldown", + "secp256k1", + "@types/bn.js", + "@types/lru-cache", + "@types/seedrandom" + ], + "hasShrinkwrap": true, + "dependencies": { + "@trufflesuite/bigint-buffer": "1.1.10", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "5.1.1", + "@types/seedrandom": "3.0.1", + "emittery": "0.10.0", + "keccak": "3.0.2", + "leveldown": "6.1.0", + "secp256k1": "4.0.3" + }, + "bin": { + "ganache": "dist/node/cli.js", + "ganache-cli": "dist/node/cli.js" + }, + "optionalDependencies": { + "bufferutil": "4.0.5", + "utf-8-validate": "5.0.7" + } + }, + "node_modules/ganache/node_modules/@trufflesuite/bigint-buffer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz", + "integrity": "sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw==", + "hasInstallScript": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "4.4.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ganache/node_modules/@trufflesuite/bigint-buffer/node_modules/node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache/node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache/node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/@types/node": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz", + "integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/@types/seedrandom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-3.0.1.tgz", + "integrity": "sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw==", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/ganache/node_modules/bufferutil": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", + "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + } + }, + "node_modules/ganache/node_modules/catering": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.0.tgz", + "integrity": "sha512-M5imwzQn6y+ODBfgi+cfgZv2hIUI6oYU/0f35Mdb1ujGeqeoI5tOnl9Q13DTH7LW+7er+NYq8stNOKZD/Z3U/A==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "queue-tick": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache/node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/emittery": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.0.tgz", + "integrity": "sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ==", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/ganache/node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/ganache/node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/ganache/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache/node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache/node_modules/keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache/node_modules/leveldown": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-6.1.0.tgz", + "integrity": "sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w==", + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^7.2.0", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/ganache/node_modules/leveldown/node_modules/abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.0.0", + "is-buffer": "^2.0.5", + "level-concat-iterator": "^3.0.0", + "level-supports": "^2.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ganache/node_modules/leveldown/node_modules/level-concat-iterator": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz", + "integrity": "sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "catering": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ganache/node_modules/leveldown/node_modules/level-supports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-2.1.0.tgz", + "integrity": "sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA==", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ganache/node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache/node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/queue-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.0.tgz", + "integrity": "sha512-ULWhjjE8BmiICGn3G8+1L9wFpERNxkf8ysxkAer4+TFdRefDaXOCV5m92aMB9FtBVmn/8sETXLXY6BfW7hyaWQ==", + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ganache/node_modules/utf-8-validate": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", + "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + } + }, + "node_modules/ganache/node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "inBundle": true, + "license": "MIT" + }, "node_modules/get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -892,21 +1366,21 @@ "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "engines": { "node": ">=0.10.0" } }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -920,7 +1394,7 @@ "node_modules/glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "integrity": "sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==", "dependencies": { "glob-parent": "^2.0.0", "is-glob": "^2.0.0" @@ -932,53 +1406,15 @@ "node_modules/glob-parent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "integrity": "sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==", "dependencies": { "is-glob": "^2.0.0" } }, - "node_modules/globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globby/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globby/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/growl": { "version": "1.10.3", @@ -999,7 +1435,7 @@ "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", "dependencies": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -1012,7 +1448,7 @@ "node_modules/has-value/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -1020,7 +1456,7 @@ "node_modules/has-values": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", "dependencies": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -1032,7 +1468,7 @@ "node_modules/has-values/node_modules/is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -1043,7 +1479,7 @@ "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dependencies": { "is-buffer": "^1.1.5" }, @@ -1054,7 +1490,7 @@ "node_modules/has-values/node_modules/kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", "dependencies": { "is-buffer": "^1.1.5" }, @@ -1065,7 +1501,7 @@ "node_modules/he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==", "bin": { "he": "bin/he" } @@ -1090,9 +1526,9 @@ } }, "node_modules/ignore": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", - "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "engines": { "node": ">= 4" } @@ -1100,7 +1536,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1114,7 +1550,7 @@ "node_modules/invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", "engines": { "node": ">=0.10.0" } @@ -1141,7 +1577,7 @@ "node_modules/is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", "dependencies": { "binary-extensions": "^1.0.0" }, @@ -1197,7 +1633,7 @@ "node_modules/is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "integrity": "sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==", "engines": { "node": ">=0.10.0" } @@ -1205,7 +1641,7 @@ "node_modules/is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "integrity": "sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA==", "dependencies": { "is-primitive": "^2.0.0" }, @@ -1216,7 +1652,7 @@ "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "engines": { "node": ">=0.10.0" } @@ -1224,7 +1660,7 @@ "node_modules/is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==", "engines": { "node": ">=0.10.0" } @@ -1240,7 +1676,7 @@ "node_modules/is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==", "dependencies": { "is-extglob": "^1.0.0" }, @@ -1251,7 +1687,7 @@ "node_modules/is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "integrity": "sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -1259,39 +1695,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "dependencies": { - "is-path-inside": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "dependencies": { - "path-is-inside": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -1306,7 +1709,7 @@ "node_modules/is-plain-object/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -1314,7 +1717,7 @@ "node_modules/is-posix-bracket": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "integrity": "sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ==", "engines": { "node": ">=0.10.0" } @@ -1322,7 +1725,7 @@ "node_modules/is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "integrity": "sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==", "engines": { "node": ">=0.10.0" } @@ -1349,17 +1752,17 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dependencies": { "isarray": "1.0.0" }, @@ -1370,7 +1773,7 @@ "node_modules/js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", "engines": { "node": ">= 0.8" } @@ -1378,12 +1781,12 @@ "node_modules/json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==" }, "node_modules/junk": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz", - "integrity": "sha1-h75jSIZJy9ym9Tqzm+yczSNH9ZI=", + "integrity": "sha512-3KF80UaaSSxo8jVnRYtMKNGFOoVPBdkkVPsw+Ad0y4oxKXPduS6G6iHkrf69yJVff/VAaYXkV42rtZ7daJxU3w==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1392,7 +1795,7 @@ "node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dependencies": { "is-buffer": "^1.1.5" }, @@ -1403,7 +1806,7 @@ "node_modules/lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", "dependencies": { "invert-kv": "^1.0.0" }, @@ -1441,7 +1844,7 @@ "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "engines": { "node": ">=0.10.0" } @@ -1449,7 +1852,7 @@ "node_modules/map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", "dependencies": { "object-visit": "^1.0.0" }, @@ -1465,7 +1868,7 @@ "node_modules/maximatch": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz", - "integrity": "sha1-hs2NawTJ8wfAWmuUGZBtA2D7E6I=", + "integrity": "sha512-9ORVtDUFk4u/NFfo0vG/ND/z7UQCVZBL539YW0+U1I7H1BkZwizcPx5foFv7LCPcBnm2U6RjFnQOsIvN4/Vm2A==", "dev": true, "dependencies": { "array-differ": "^1.0.0", @@ -1480,7 +1883,7 @@ "node_modules/maximatch/node_modules/array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1489,7 +1892,7 @@ "node_modules/maximatch/node_modules/array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, "dependencies": { "array-uniq": "^1.0.1" @@ -1501,7 +1904,7 @@ "node_modules/maximatch/node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1510,7 +1913,7 @@ "node_modules/mem": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "integrity": "sha512-nOBDrc/wgpkd3X/JOhMqYR+/eLqlfLP4oQfoBA6QExIxEl+GU01oyEkwWyueyO8110pUKijtiHGhEmYoOn88oQ==", "dependencies": { "mimic-fn": "^1.0.0" }, @@ -1534,7 +1937,7 @@ "node_modules/micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "integrity": "sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA==", "dependencies": { "arr-diff": "^2.0.0", "array-unique": "^0.2.1", @@ -1563,9 +1966,9 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1574,9 +1977,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "node_modules/mixin-deep": { @@ -1603,12 +2006,12 @@ } }, "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "dependencies": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" @@ -1654,7 +2057,7 @@ "node_modules/mocha/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { "node": ">=0.8.0" } @@ -1678,7 +2081,7 @@ "node_modules/mocha/node_modules/has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==", "engines": { "node": ">=0.10.0" } @@ -1686,12 +2089,12 @@ "node_modules/mocha/node_modules/minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==" }, "node_modules/mocha/node_modules/mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "dependencies": { "minimist": "0.0.8" @@ -1722,7 +2125,7 @@ "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/multimatch": { "version": "4.0.0", @@ -1740,9 +2143,9 @@ } }, "node_modules/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", "optional": true }, "node_modules/nanomatch": { @@ -1769,7 +2172,7 @@ "node_modules/nanomatch/node_modules/arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "engines": { "node": ">=0.10.0" } @@ -1777,7 +2180,7 @@ "node_modules/nanomatch/node_modules/array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "engines": { "node": ">=0.10.0" } @@ -1793,7 +2196,7 @@ "node_modules/normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dependencies": { "remove-trailing-separator": "^1.0.1" }, @@ -1815,16 +2218,7 @@ "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "engines": { "node": ">=0.10.0" } @@ -1832,7 +2226,7 @@ "node_modules/object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "dependencies": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -1845,7 +2239,7 @@ "node_modules/object-copy/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dependencies": { "is-descriptor": "^0.1.0" }, @@ -1856,7 +2250,7 @@ "node_modules/object-copy/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dependencies": { "kind-of": "^3.0.2" }, @@ -1867,7 +2261,7 @@ "node_modules/object-copy/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -1899,7 +2293,7 @@ "node_modules/object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "dependencies": { "isobject": "^3.0.0" }, @@ -1910,7 +2304,7 @@ "node_modules/object-visit/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -1918,7 +2312,7 @@ "node_modules/object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "integrity": "sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA==", "dependencies": { "for-own": "^0.1.4", "is-extendable": "^0.1.1" @@ -1930,7 +2324,7 @@ "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dependencies": { "isobject": "^3.0.1" }, @@ -1941,7 +2335,7 @@ "node_modules/object.pick/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -1949,7 +2343,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } @@ -1984,7 +2378,7 @@ "node_modules/os-locale/node_modules/cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "dependencies": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -1994,7 +2388,7 @@ "node_modules/os-locale/node_modules/execa": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", "dependencies": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", @@ -2011,7 +2405,7 @@ "node_modules/os-locale/node_modules/get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", "engines": { "node": ">=4" } @@ -2019,7 +2413,7 @@ "node_modules/os-locale/node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "engines": { "node": ">=0.10.0" } @@ -2036,7 +2430,7 @@ "node_modules/os-locale/node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "dependencies": { "path-key": "^2.0.0" }, @@ -2047,7 +2441,7 @@ "node_modules/os-locale/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "engines": { "node": ">=4" } @@ -2055,7 +2449,7 @@ "node_modules/os-locale/node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dependencies": { "shebang-regex": "^1.0.0" }, @@ -2066,7 +2460,7 @@ "node_modules/os-locale/node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "engines": { "node": ">=0.10.0" } @@ -2085,12 +2479,12 @@ "node_modules/os-locale/node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "engines": { "node": ">=4" } @@ -2131,7 +2525,7 @@ "node_modules/parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "integrity": "sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==", "dependencies": { "glob-base": "^0.3.0", "is-dotfile": "^1.0.0", @@ -2145,7 +2539,7 @@ "node_modules/pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", "engines": { "node": ">=0.10.0" } @@ -2161,17 +2555,11 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2183,7 +2571,7 @@ "node_modules/pegjs": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", + "integrity": "sha512-qI5+oFNEGi3L5HAxDwN2LA4Gg7irF70Zs25edhjld9QemOgp0CbvMtbFcMvFtEo1OityPrcCzkQFB8JP/hxgow==", "bin": { "pegjs": "bin/pegjs" }, @@ -2194,37 +2582,16 @@ "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "engines": { "node": ">=0.10.0" } @@ -2232,31 +2599,34 @@ "node_modules/preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "integrity": "sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/prettier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz", - "integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-plugin-solidity": { - "version": "1.0.0-beta.19", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", - "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", + "version": "1.0.0-dev.22", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-dev.22.tgz", + "integrity": "sha512-0v+O2/sqq6WMlZ2TsnRBXaNmKF4zANn0uLLWuvNra4BjmKUtp33EZ4AVKB26fzWy14BkVGeJfPAtKry0x3SFfQ==", "dependencies": { - "@solidity-parser/parser": "^0.14.0", - "emoji-regex": "^10.0.0", + "@solidity-parser/parser": "^0.14.2", + "emoji-regex": "^10.1.0", "escape-string-regexp": "^4.0.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "solidity-comments-extractor": "^0.0.7", "string-width": "^4.2.3" }, @@ -2268,9 +2638,9 @@ } }, "node_modules/pretty-quick": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz", - "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz", + "integrity": "sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==", "dependencies": { "chalk": "^3.0.0", "execa": "^4.0.0", @@ -2306,13 +2676,13 @@ "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "node_modules/pump": { "version": "3.0.0", @@ -2382,7 +2752,7 @@ "node_modules/readdirp/node_modules/arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "engines": { "node": ">=0.10.0" } @@ -2390,7 +2760,7 @@ "node_modules/readdirp/node_modules/array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "engines": { "node": ">=0.10.0" } @@ -2418,7 +2788,7 @@ "node_modules/readdirp/node_modules/braces/node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -2437,7 +2807,7 @@ "node_modules/readdirp/node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", "dependencies": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -2454,7 +2824,7 @@ "node_modules/readdirp/node_modules/expand-brackets/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dependencies": { "is-descriptor": "^0.1.0" }, @@ -2465,7 +2835,7 @@ "node_modules/readdirp/node_modules/expand-brackets/node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -2515,7 +2885,7 @@ "node_modules/readdirp/node_modules/extglob/node_modules/define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dependencies": { "is-descriptor": "^1.0.0" }, @@ -2526,7 +2896,7 @@ "node_modules/readdirp/node_modules/extglob/node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -2537,7 +2907,7 @@ "node_modules/readdirp/node_modules/fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", "dependencies": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -2551,7 +2921,7 @@ "node_modules/readdirp/node_modules/fill-range/node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -2562,7 +2932,7 @@ "node_modules/readdirp/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dependencies": { "kind-of": "^3.0.2" }, @@ -2573,7 +2943,7 @@ "node_modules/readdirp/node_modules/is-accessor-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dependencies": { "is-buffer": "^1.1.5" }, @@ -2584,7 +2954,7 @@ "node_modules/readdirp/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -2595,7 +2965,7 @@ "node_modules/readdirp/node_modules/is-data-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dependencies": { "is-buffer": "^1.1.5" }, @@ -2606,7 +2976,7 @@ "node_modules/readdirp/node_modules/is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -2617,7 +2987,7 @@ "node_modules/readdirp/node_modules/is-number/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dependencies": { "is-buffer": "^1.1.5" }, @@ -2628,7 +2998,7 @@ "node_modules/readdirp/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -2665,13 +3035,11 @@ } }, "node_modules/recursive-copy": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.13.tgz", - "integrity": "sha512-BjmE6R/dOImStEku+017L3Z0I6u/lA+SVr1sySWbTLjmQKDTESNmJ9WBZP8wbN5FuvqNvSYvRKA/IKQhAjqnpQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.14.tgz", + "integrity": "sha512-K8WNY8f8naTpfbA+RaXmkaQuD1IeW9EgNEfyGxSqqTQukpVtoOKros9jUqbpEsSw59YOmpd8nCBgtqJZy5nvog==", "dev": true, - "license": "ISC", "dependencies": { - "del": "^2.2.0", "errno": "^0.1.2", "graceful-fs": "^4.1.4", "junk": "^1.0.1", @@ -2679,6 +3047,7 @@ "mkdirp": "^0.5.1", "pify": "^2.3.0", "promise": "^7.0.1", + "rimraf": "^2.7.1", "slash": "^1.0.0" } }, @@ -2708,7 +3077,7 @@ "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" }, "node_modules/repeat-element": { "version": "1.1.4", @@ -2721,7 +3090,7 @@ "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "engines": { "node": ">=0.10" } @@ -2729,7 +3098,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { "node": ">=0.10.0" } @@ -2737,12 +3106,12 @@ "node_modules/require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" }, "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", "deprecated": "https://github.com/lydell/resolve-url#deprecated" }, "node_modules/ret": { @@ -2773,15 +3142,15 @@ "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "dependencies": { "ret": "~0.1.10" } }, "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2795,7 +3164,7 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-value": { "version": "2.0.1", @@ -2814,7 +3183,7 @@ "node_modules/set-value/node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -2842,14 +3211,14 @@ } }, "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -2889,7 +3258,7 @@ "node_modules/snapdragon-node/node_modules/define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dependencies": { "is-descriptor": "^1.0.0" }, @@ -2900,7 +3269,7 @@ "node_modules/snapdragon-node/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -2927,7 +3296,7 @@ "node_modules/snapdragon/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dependencies": { "is-descriptor": "^0.1.0" }, @@ -2938,7 +3307,7 @@ "node_modules/snapdragon/node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -2949,7 +3318,7 @@ "node_modules/snapdragon/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dependencies": { "kind-of": "^3.0.2" }, @@ -2960,7 +3329,7 @@ "node_modules/snapdragon/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -2992,12 +3361,12 @@ "node_modules/sol-digger": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/sol-digger/-/sol-digger-0.0.2.tgz", - "integrity": "sha1-QGxKnTHiaef4jrHC6hATGOXgkCU=" + "integrity": "sha512-oqrw1E/X2WWYUYCzKDM5INDDH2nWOWos4p2Cw2OF52qoZcTDzlKMJQ5pJFXKOCADCg6KggBO5WYE/vNb+kJ0Hg==" }, "node_modules/sol-explore": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.1.tgz", - "integrity": "sha1-tZ8HPGn+MyVg1aEMMrqMp/KYbPs=" + "integrity": "sha512-cmwg7l+QLj2LE3Qvwrdo4aPYcNYY425+bN5VPkgCjkO0CiSz33G5vM5BmMZNrfd/6yNGwcm0KtwDJmh5lUElEQ==" }, "node_modules/solidity-comments-extractor": { "version": "0.0.7", @@ -3052,7 +3421,7 @@ "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { "node": ">=0.10.0" } @@ -3061,6 +3430,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -3072,7 +3442,8 @@ "node_modules/source-map-url": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated" }, "node_modules/split-string": { "version": "3.1.0", @@ -3088,7 +3459,7 @@ "node_modules/static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", "dependencies": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -3100,7 +3471,7 @@ "node_modules/static-extend/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dependencies": { "is-descriptor": "^0.1.0" }, @@ -3111,7 +3482,7 @@ "node_modules/static-extend/node_modules/is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "dependencies": { "kind-of": "^3.0.2" }, @@ -3122,7 +3493,7 @@ "node_modules/static-extend/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -3191,7 +3562,7 @@ "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", "engines": { "node": ">=0.10.0" } @@ -3218,12 +3589,12 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -3248,7 +3619,7 @@ "node_modules/to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "dependencies": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -3260,7 +3631,7 @@ "node_modules/to-regex-range/node_modules/is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dependencies": { "kind-of": "^3.0.2" }, @@ -3285,7 +3656,7 @@ "node_modules/unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "dependencies": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -3297,7 +3668,7 @@ "node_modules/unset-value/node_modules/has-value": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", "dependencies": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -3310,7 +3681,7 @@ "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dependencies": { "isarray": "1.0.0" }, @@ -3321,7 +3692,7 @@ "node_modules/unset-value/node_modules/has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", "engines": { "node": ">=0.10.0" } @@ -3329,7 +3700,7 @@ "node_modules/unset-value/node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -3337,7 +3708,7 @@ "node_modules/urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", "deprecated": "Please see https://github.com/lydell/urix#deprecated" }, "node_modules/use": { @@ -3351,7 +3722,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/which": { "version": "2.0.2", @@ -3370,12 +3741,12 @@ "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "node_modules/wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -3387,7 +3758,7 @@ "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "engines": { "node": ">=0.10.0" } @@ -3395,7 +3766,7 @@ "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "dependencies": { "number-is-nan": "^1.0.0" }, @@ -3406,7 +3777,7 @@ "node_modules/wrap-ansi/node_modules/string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3419,7 +3790,7 @@ "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -3430,7 +3801,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/y18n": { "version": "3.2.2", @@ -3470,9 +3841,9 @@ } }, "node_modules/yargs/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "engines": { "node": ">=4" } @@ -3480,7 +3851,7 @@ "node_modules/yargs/node_modules/find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dependencies": { "locate-path": "^2.0.0" }, @@ -3491,7 +3862,7 @@ "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "engines": { "node": ">=4" } @@ -3499,7 +3870,7 @@ "node_modules/yargs/node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -3522,7 +3893,7 @@ "node_modules/yargs/node_modules/p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dependencies": { "p-limit": "^1.1.0" }, @@ -3533,7 +3904,7 @@ "node_modules/yargs/node_modules/p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "engines": { "node": ">=4" } @@ -3541,7 +3912,7 @@ "node_modules/yargs/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "engines": { "node": ">=4" } @@ -3561,7 +3932,7 @@ "node_modules/yargs/node_modules/strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dependencies": { "ansi-regex": "^3.0.0" }, @@ -3571,15 +3942,10 @@ } }, "dependencies": { - "@openzeppelin/contracts": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.4.0.tgz", - "integrity": "sha512-dlKiZmDvJnGRLHojrDoFZJmsQVeltVeoiRN7RK+cf2FmkhASDEblE0RiaYdxPNsUZa6mRG8393b9bfyp+V5IAw==" - }, "@solidity-parser/parser": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.0.tgz", - "integrity": "sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", + "integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==", "requires": { "antlr4ts": "^0.5.0-alpha.4" } @@ -3592,7 +3958,7 @@ "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", @@ -3630,7 +3996,7 @@ "arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "integrity": "sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==", "requires": { "arr-flatten": "^1.0.1" } @@ -3643,7 +4009,7 @@ "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==" }, "array-differ": { "version": "3.0.0", @@ -3658,13 +4024,13 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==" }, "arrify": { "version": "2.0.1", @@ -3674,13 +4040,13 @@ "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==" }, "async-each": { "version": "1.0.3", @@ -3714,7 +4080,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "requires": { "is-descriptor": "^1.0.0" } @@ -3722,7 +4088,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, @@ -3752,7 +4118,7 @@ "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "integrity": "sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==", "requires": { "expand-range": "^1.8.1", "preserve": "^0.2.0", @@ -3762,7 +4128,7 @@ "browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" + "integrity": "sha512-7Rfk377tpSM9TWBEeHs0FlDZGoAIei2V/4MdZJoFMBFAK6BqLpxAIUepGRHGdPFgGsLb02PXovC4qddyHvQqTg==" }, "cache-base": { "version": "1.0.1", @@ -3783,14 +4149,14 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==" }, "chalk": { "version": "3.0.0", @@ -3804,7 +4170,7 @@ "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "integrity": "sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==", "requires": { "anymatch": "^1.3.0", "async-each": "^1.0.0", @@ -3831,7 +4197,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "requires": { "is-descriptor": "^0.1.0" } @@ -3839,7 +4205,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "requires": { "kind-of": "^3.0.2" } @@ -3847,7 +4213,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "requires": { "kind-of": "^3.0.2" } @@ -3872,7 +4238,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, @@ -3887,14 +4253,14 @@ }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "string-width": { "version": "2.1.1", @@ -3908,7 +4274,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "requires": { "ansi-regex": "^3.0.0" } @@ -3918,17 +4284,17 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==" }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==" }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -3965,12 +4331,12 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==" }, "core-util-is": { "version": "1.0.3", @@ -3998,12 +4364,12 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" }, "define-property": { "version": "2.0.2", @@ -4017,34 +4383,19 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, "emoji-regex": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.0.0.tgz", - "integrity": "sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw==" + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", + "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==" }, "end-of-stream": { "version": "1.4.4", @@ -4112,7 +4463,7 @@ "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "integrity": "sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==", "requires": { "is-posix-bracket": "^0.1.0" } @@ -4120,7 +4471,7 @@ "expand-range": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "integrity": "sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==", "requires": { "fill-range": "^2.1.0" } @@ -4128,7 +4479,7 @@ "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -4147,7 +4498,7 @@ "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "integrity": "sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==", "requires": { "is-extglob": "^1.0.0" } @@ -4155,7 +4506,7 @@ "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==" }, "fast-json-stable-stringify": { "version": "2.1.0", @@ -4171,7 +4522,7 @@ "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + "integrity": "sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ==" }, "fill-range": { "version": "2.2.4", @@ -4197,12 +4548,12 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==" }, "for-own": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "integrity": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", "requires": { "for-in": "^1.0.1" } @@ -4210,7 +4561,7 @@ "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", "requires": { "map-cache": "^0.2.2" } @@ -4218,7 +4569,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "1.2.13", @@ -4230,6 +4581,324 @@ "nan": "^2.12.1" } }, + "ganache": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ganache/-/ganache-7.4.3.tgz", + "integrity": "sha512-RpEDUiCkqbouyE7+NMXG26ynZ+7sGiODU84Kz+FVoXUnQ4qQM4M8wif3Y4qUCt+D/eM1RVeGq0my62FPD6Y1KA==", + "requires": { + "@trufflesuite/bigint-buffer": "1.1.10", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "5.1.1", + "@types/seedrandom": "3.0.1", + "bufferutil": "4.0.5", + "emittery": "0.10.0", + "keccak": "3.0.2", + "leveldown": "6.1.0", + "secp256k1": "4.0.3", + "utf-8-validate": "5.0.7" + }, + "dependencies": { + "@trufflesuite/bigint-buffer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz", + "integrity": "sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw==", + "bundled": true, + "requires": { + "node-gyp-build": "4.4.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "bundled": true + } + } + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "bundled": true, + "requires": { + "@types/node": "*" + } + }, + "@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "bundled": true + }, + "@types/node": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz", + "integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==", + "bundled": true + }, + "@types/seedrandom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-3.0.1.tgz", + "integrity": "sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw==", + "bundled": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "bundled": true + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "bundled": true + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "bundled": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "bufferutil": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", + "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "catering": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.0.tgz", + "integrity": "sha512-M5imwzQn6y+ODBfgi+cfgZv2hIUI6oYU/0f35Mdb1ujGeqeoI5tOnl9Q13DTH7LW+7er+NYq8stNOKZD/Z3U/A==", + "bundled": true, + "requires": { + "queue-tick": "^1.0.0" + } + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "bundled": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "bundled": true + } + } + }, + "emittery": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.0.tgz", + "integrity": "sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ==", + "bundled": true + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "bundled": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "bundled": true + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "bundled": true + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "bundled": true + }, + "keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "bundled": true, + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + } + }, + "leveldown": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-6.1.0.tgz", + "integrity": "sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w==", + "bundled": true, + "requires": { + "abstract-leveldown": "^7.2.0", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ==", + "bundled": true, + "requires": { + "buffer": "^6.0.3", + "catering": "^2.0.0", + "is-buffer": "^2.0.5", + "level-concat-iterator": "^3.0.0", + "level-supports": "^2.0.1", + "queue-microtask": "^1.2.3" + } + }, + "level-concat-iterator": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz", + "integrity": "sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ==", + "bundled": true, + "requires": { + "catering": "^2.1.0" + } + }, + "level-supports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-2.1.0.tgz", + "integrity": "sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA==", + "bundled": true + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "bundled": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "bundled": true + }, + "napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "bundled": true + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "bundled": true + }, + "node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "bundled": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "bundled": true + }, + "queue-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.0.tgz", + "integrity": "sha512-ULWhjjE8BmiICGn3G8+1L9wFpERNxkf8ysxkAer4+TFdRefDaXOCV5m92aMB9FtBVmn/8sETXLXY6BfW7hyaWQ==", + "bundled": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "bundled": true + }, + "secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "bundled": true, + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "bundled": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "utf-8-validate": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", + "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true + } + } + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -4246,18 +4915,18 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==" }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -4265,7 +4934,7 @@ "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "integrity": "sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==", "requires": { "glob-parent": "^2.0.0", "is-glob": "^2.0.0" @@ -4274,46 +4943,15 @@ "glob-parent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "integrity": "sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==", "requires": { "is-glob": "^2.0.0" } }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - } - } - }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "growl": { "version": "1.10.3", @@ -4328,7 +4966,7 @@ "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -4338,14 +4976,14 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, "has-values": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -4354,7 +4992,7 @@ "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "requires": { "kind-of": "^3.0.2" }, @@ -4362,7 +5000,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "requires": { "is-buffer": "^1.1.5" } @@ -4372,7 +5010,7 @@ "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", "requires": { "is-buffer": "^1.1.5" } @@ -4382,7 +5020,7 @@ "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + "integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==" }, "human-signals": { "version": "1.1.1", @@ -4395,14 +5033,14 @@ "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==" }, "ignore": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", - "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4416,7 +5054,7 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==" }, "is-accessor-descriptor": { "version": "1.0.0", @@ -4436,7 +5074,7 @@ "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", "requires": { "binary-extensions": "^1.0.0" } @@ -4481,12 +5119,12 @@ "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + "integrity": "sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==" }, "is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "integrity": "sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA==", "requires": { "is-primitive": "^2.0.0" } @@ -4494,12 +5132,12 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" }, "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -4509,7 +5147,7 @@ "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==", "requires": { "is-extglob": "^1.0.0" } @@ -4517,35 +5155,11 @@ "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "integrity": "sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==", "requires": { "kind-of": "^3.0.2" } }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4557,19 +5171,19 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, "is-posix-bracket": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + "integrity": "sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ==" }, "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + "integrity": "sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==" }, "is-stream": { "version": "2.0.1", @@ -4584,17 +5198,17 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "requires": { "isarray": "1.0.0" } @@ -4602,23 +5216,23 @@ "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=" + "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==" }, "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==" }, "junk": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz", - "integrity": "sha1-h75jSIZJy9ym9Tqzm+yczSNH9ZI=", + "integrity": "sha512-3KF80UaaSSxo8jVnRYtMKNGFOoVPBdkkVPsw+Ad0y4oxKXPduS6G6iHkrf69yJVff/VAaYXkV42rtZ7daJxU3w==", "dev": true }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "requires": { "is-buffer": "^1.1.5" } @@ -4626,7 +5240,7 @@ "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", "requires": { "invert-kv": "^1.0.0" } @@ -4655,12 +5269,12 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", "requires": { "object-visit": "^1.0.0" } @@ -4673,7 +5287,7 @@ "maximatch": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz", - "integrity": "sha1-hs2NawTJ8wfAWmuUGZBtA2D7E6I=", + "integrity": "sha512-9ORVtDUFk4u/NFfo0vG/ND/z7UQCVZBL539YW0+U1I7H1BkZwizcPx5foFv7LCPcBnm2U6RjFnQOsIvN4/Vm2A==", "dev": true, "requires": { "array-differ": "^1.0.0", @@ -4685,13 +5299,13 @@ "array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==", "dev": true }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, "requires": { "array-uniq": "^1.0.1" @@ -4700,7 +5314,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true } } @@ -4708,7 +5322,7 @@ "mem": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "integrity": "sha512-nOBDrc/wgpkd3X/JOhMqYR+/eLqlfLP4oQfoBA6QExIxEl+GU01oyEkwWyueyO8110pUKijtiHGhEmYoOn88oQ==", "requires": { "mimic-fn": "^1.0.0" }, @@ -4728,7 +5342,7 @@ "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "integrity": "sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA==", "requires": { "arr-diff": "^2.0.0", "array-unique": "^0.2.1", @@ -4751,17 +5365,17 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "mixin-deep": { @@ -4784,12 +5398,12 @@ } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" } }, "mocha": { @@ -4822,7 +5436,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "glob": { "version": "7.1.2", @@ -4840,17 +5454,17 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==" }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==" }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", "requires": { "minimist": "0.0.8" } @@ -4873,7 +5487,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "multimatch": { "version": "4.0.0", @@ -4888,9 +5502,9 @@ } }, "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", "optional": true }, "nanomatch": { @@ -4914,12 +5528,12 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==" }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==" }, "kind-of": { "version": "6.0.3", @@ -4931,7 +5545,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "requires": { "remove-trailing-separator": "^1.0.1" } @@ -4947,18 +5561,12 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -4968,7 +5576,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "requires": { "is-descriptor": "^0.1.0" } @@ -4976,7 +5584,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "requires": { "kind-of": "^3.0.2" } @@ -4984,7 +5592,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "requires": { "kind-of": "^3.0.2" } @@ -5011,7 +5619,7 @@ "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "requires": { "isobject": "^3.0.0" }, @@ -5019,14 +5627,14 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "integrity": "sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA==", "requires": { "for-own": "^0.1.4", "is-extendable": "^0.1.1" @@ -5035,7 +5643,7 @@ "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "requires": { "isobject": "^3.0.1" }, @@ -5043,14 +5651,14 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -5076,7 +5684,7 @@ "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -5086,7 +5694,7 @@ "execa": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", "requires": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", @@ -5100,12 +5708,12 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==" }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" }, "lru-cache": { "version": "4.1.5", @@ -5119,7 +5727,7 @@ "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "requires": { "path-key": "^2.0.0" } @@ -5127,12 +5735,12 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "requires": { "shebang-regex": "^1.0.0" } @@ -5140,7 +5748,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" }, "which": { "version": "1.3.1", @@ -5153,14 +5761,14 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" } } }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" }, "p-limit": { "version": "2.3.0", @@ -5186,7 +5794,7 @@ "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "integrity": "sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==", "requires": { "glob-base": "^0.3.0", "is-dotfile": "^1.0.0", @@ -5197,7 +5805,7 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==" }, "path-exists": { "version": "4.0.0", @@ -5207,13 +5815,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -5223,61 +5825,46 @@ "pegjs": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=" + "integrity": "sha512-qI5+oFNEGi3L5HAxDwN2LA4Gg7irF70Zs25edhjld9QemOgp0CbvMtbFcMvFtEo1OityPrcCzkQFB8JP/hxgow==" }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==" }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + "integrity": "sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==" }, "prettier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz", - "integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==" + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==" }, "prettier-plugin-solidity": { - "version": "1.0.0-beta.19", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", - "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", + "version": "1.0.0-dev.22", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-dev.22.tgz", + "integrity": "sha512-0v+O2/sqq6WMlZ2TsnRBXaNmKF4zANn0uLLWuvNra4BjmKUtp33EZ4AVKB26fzWy14BkVGeJfPAtKry0x3SFfQ==", "requires": { - "@solidity-parser/parser": "^0.14.0", - "emoji-regex": "^10.0.0", + "@solidity-parser/parser": "^0.14.2", + "emoji-regex": "^10.1.0", "escape-string-regexp": "^4.0.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "solidity-comments-extractor": "^0.0.7", "string-width": "^4.2.3" } }, "pretty-quick": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz", - "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz", + "integrity": "sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==", "requires": { "chalk": "^3.0.0", "execa": "^4.0.0", @@ -5304,13 +5891,13 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "pump": { "version": "3.0.0", @@ -5370,12 +5957,12 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==" }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==" }, "braces": { "version": "2.3.2", @@ -5397,7 +5984,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } @@ -5415,7 +6002,7 @@ "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -5429,7 +6016,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "requires": { "is-descriptor": "^0.1.0" } @@ -5437,7 +6024,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } @@ -5477,7 +6064,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "requires": { "is-descriptor": "^1.0.0" } @@ -5485,7 +6072,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } @@ -5495,7 +6082,7 @@ "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -5506,7 +6093,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } @@ -5516,7 +6103,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "requires": { "kind-of": "^3.0.2" }, @@ -5524,7 +6111,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "requires": { "is-buffer": "^1.1.5" } @@ -5534,7 +6121,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "requires": { "kind-of": "^3.0.2" }, @@ -5542,7 +6129,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "requires": { "is-buffer": "^1.1.5" } @@ -5552,7 +6139,7 @@ "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "requires": { "kind-of": "^3.0.2" }, @@ -5560,7 +6147,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "requires": { "is-buffer": "^1.1.5" } @@ -5570,7 +6157,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "kind-of": { "version": "6.0.3", @@ -5600,12 +6187,11 @@ } }, "recursive-copy": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.13.tgz", - "integrity": "sha512-BjmE6R/dOImStEku+017L3Z0I6u/lA+SVr1sySWbTLjmQKDTESNmJ9WBZP8wbN5FuvqNvSYvRKA/IKQhAjqnpQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.14.tgz", + "integrity": "sha512-K8WNY8f8naTpfbA+RaXmkaQuD1IeW9EgNEfyGxSqqTQukpVtoOKros9jUqbpEsSw59YOmpd8nCBgtqJZy5nvog==", "dev": true, "requires": { - "del": "^2.2.0", "errno": "^0.1.2", "graceful-fs": "^4.1.4", "junk": "^1.0.1", @@ -5613,6 +6199,7 @@ "mkdirp": "^0.5.1", "pify": "^2.3.0", "promise": "^7.0.1", + "rimraf": "^2.7.1", "slash": "^1.0.0" } }, @@ -5636,7 +6223,7 @@ "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" }, "repeat-element": { "version": "1.1.4", @@ -5646,22 +6233,22 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" }, "ret": { "version": "0.1.15", @@ -5685,15 +6272,15 @@ "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "requires": { "ret": "~0.1.10" } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "requires": { "lru-cache": "^6.0.0" } @@ -5701,7 +6288,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "set-value": { "version": "2.0.1", @@ -5717,7 +6304,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } @@ -5738,14 +6325,14 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true }, "snapdragon": { @@ -5774,7 +6361,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "requires": { "is-descriptor": "^0.1.0" } @@ -5782,7 +6369,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } @@ -5790,7 +6377,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "requires": { "kind-of": "^3.0.2" } @@ -5798,7 +6385,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "requires": { "kind-of": "^3.0.2" } @@ -5835,7 +6422,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "requires": { "is-descriptor": "^1.0.0" } @@ -5843,7 +6430,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, @@ -5858,12 +6445,12 @@ "sol-digger": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/sol-digger/-/sol-digger-0.0.2.tgz", - "integrity": "sha1-QGxKnTHiaef4jrHC6hATGOXgkCU=" + "integrity": "sha512-oqrw1E/X2WWYUYCzKDM5INDDH2nWOWos4p2Cw2OF52qoZcTDzlKMJQ5pJFXKOCADCg6KggBO5WYE/vNb+kJ0Hg==" }, "sol-explore": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.1.tgz", - "integrity": "sha1-tZ8HPGn+MyVg1aEMMrqMp/KYbPs=" + "integrity": "sha512-cmwg7l+QLj2LE3Qvwrdo4aPYcNYY425+bN5VPkgCjkO0CiSz33G5vM5BmMZNrfd/6yNGwcm0KtwDJmh5lUElEQ==" }, "solidity-comments-extractor": { "version": "0.0.7", @@ -5910,7 +6497,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" }, "source-map-resolve": { "version": "0.5.3", @@ -5940,7 +6527,7 @@ "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -5949,7 +6536,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "requires": { "is-descriptor": "^0.1.0" } @@ -5957,7 +6544,7 @@ "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", "requires": { "kind-of": "^3.0.2" } @@ -5965,7 +6552,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", "requires": { "kind-of": "^3.0.2" } @@ -6025,7 +6612,7 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==" }, "strip-final-newline": { "version": "2.0.0", @@ -6043,12 +6630,12 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", "requires": { "kind-of": "^3.0.2" } @@ -6067,7 +6654,7 @@ "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -6076,7 +6663,7 @@ "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "requires": { "kind-of": "^3.0.2" } @@ -6097,7 +6684,7 @@ "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -6106,7 +6693,7 @@ "has-value": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -6116,7 +6703,7 @@ "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "requires": { "isarray": "1.0.0" } @@ -6126,19 +6713,19 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" } } }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==" }, "use": { "version": "3.1.1", @@ -6148,7 +6735,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "which": { "version": "2.0.2", @@ -6161,12 +6748,12 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -6175,12 +6762,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "requires": { "number-is-nan": "^1.0.0" } @@ -6188,7 +6775,7 @@ "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6198,7 +6785,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "requires": { "ansi-regex": "^2.0.0" } @@ -6208,7 +6795,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "y18n": { "version": "3.2.2", @@ -6240,14 +6827,14 @@ }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==" }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "requires": { "locate-path": "^2.0.0" } @@ -6255,12 +6842,12 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -6277,7 +6864,7 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "requires": { "p-limit": "^1.1.0" } @@ -6285,12 +6872,12 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==" }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" }, "string-width": { "version": "2.1.1", @@ -6304,7 +6891,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "requires": { "ansi-regex": "^3.0.0" } diff --git a/package.json b/package.json index d41fd696..1b98414f 100644 --- a/package.json +++ b/package.json @@ -5,18 +5,18 @@ "author": "Bogdan Kovtun ", "license": "GPL-3.0", "dependencies": { - "@openzeppelin/contracts": "^4.3.2", "ethlint": "^1.2.5", + "ganache": "^7.9.1", "husky": "^6.0.0", "prettier": "^2.3.0", "prettier-plugin-solidity": "^1.0.0-beta.10", - "pretty-quick": "^3.1.0" + "pretty-quick": "^3.1.0", + "@openzeppelin/contracts-v4.3.2": "npm:@openzeppelin/contracts@4.3.2" }, "scripts": { "lint": "pretty-quick --pattern '**/*.*(sol|json)' --verbose", "lint:check": "prettier --check **/*.sol **/*.json", - "lint:fix": "pretty-quick --pattern '**/*.*(sol|json)' --staged --verbose", - "postinstall": "node postinstall.js" + "lint:fix": "pretty-quick --pattern '**/*.*(sol|json)' --staged --verbose" }, "husky": { "hooks": { diff --git a/poetry.lock b/poetry.lock index 8c493b4f..6f4c2267 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,164 +1,670 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + [[package]] name = "aiohttp" -version = "3.8.1" +version = "3.9.3" description = "Async http client/server framework (asyncio)" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54"}, + {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc"}, + {file = "aiohttp-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52"}, + {file = "aiohttp-3.9.3-cp310-cp310-win32.whl", hash = "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b"}, + {file = "aiohttp-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4"}, + {file = "aiohttp-3.9.3-cp311-cp311-win32.whl", hash = "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5"}, + {file = "aiohttp-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f"}, + {file = "aiohttp-3.9.3-cp312-cp312-win32.whl", hash = "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38"}, + {file = "aiohttp-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5"}, + {file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c"}, + {file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528"}, + {file = "aiohttp-3.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2"}, + {file = "aiohttp-3.9.3-cp38-cp38-win32.whl", hash = "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63"}, + {file = "aiohttp-3.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c"}, + {file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29"}, + {file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1"}, + {file = "aiohttp-3.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d"}, + {file = "aiohttp-3.9.3-cp39-cp39-win32.whl", hash = "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051"}, + {file = "aiohttp-3.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc"}, + {file = "aiohttp-3.9.3.tar.gz", hash = "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7"}, +] [package.dependencies] aiosignal = ">=1.1.2" -async-timeout = ">=4.0.0a3,<5.0" +async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} attrs = ">=17.3.0" -charset-normalizer = ">=2.0,<3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" yarl = ">=1.0,<2.0" [package.extras] -speedups = ["aiodns", "brotli", "cchardet"] +speedups = ["Brotli", "aiodns", "brotlicffi"] [[package]] name = "aiosignal" -version = "1.2.0" +version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] [package.dependencies] frozenlist = ">=1.1.0" [[package]] name = "asttokens" -version = "2.0.5" +version = "2.4.1" description = "Annotate AST trees with source code positions" -category = "main" optional = false python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] [package.dependencies] -six = "*" +six = ">=1.12.0" [package.extras] -test = ["astroid", "pytest"] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "async-timeout" -version = "4.0.2" +version = "4.0.3" description = "Timeout context manager for asyncio programs" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] [[package]] name = "atomicwrites" -version = "1.4.0" +version = "1.4.1" description = "Atomic file writes." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +] [[package]] name = "attrs" -version = "21.4.0" +version = "23.2.0" description = "Classes Without Boilerplate" -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] - -[[package]] -name = "base58" -version = "2.1.1" -description = "Base58 and Base58Check implementation." -category = "main" -optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] [package.extras] -tests = ["mypy", "PyHamcrest (>=2.0.2)", "pytest (>=4.6)", "pytest-benchmark", "pytest-cov", "pytest-flake8"] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "bitarray" -version = "1.2.2" +version = "2.9.2" description = "efficient arrays of booleans -- C extension" -category = "main" optional = false python-versions = "*" +files = [ + {file = "bitarray-2.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:917905de565d9576eb20f53c797c15ba88b9f4f19728acabec8d01eee1d3756a"}, + {file = "bitarray-2.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b35bfcb08b7693ab4bf9059111a6e9f14e07d57ac93cd967c420db58ab9b71e1"}, + {file = "bitarray-2.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ea1923d2e7880f9e1959e035da661767b5a2e16a45dfd57d6aa831e8b65ee1bf"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0b63a565e8a311cc8348ff1262d5784df0f79d64031d546411afd5dd7ef67d"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf0620da2b81946d28c0b16f3e3704d38e9837d85ee4f0652816e2609aaa4fed"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79a9b8b05f2876c7195a2b698c47528e86a73c61ea203394ff8e7a4434bda5c8"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:345c76b349ff145549652436235c5532e5bfe9db690db6f0a6ad301c62b9ef21"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e2936f090bf3f4d1771f44f9077ebccdbc0415d2b598d51a969afcb519df505"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f9346e98fc2abcef90b942973087e2462af6d3e3710e82938078d3493f7fef52"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e6ec283d4741befb86e8c3ea2e9ac1d17416c956d392107e45263e736954b1f7"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:962892646599529917ef26266091e4cb3077c88b93c3833a909d68dcc971c4e3"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e8da5355d7d75a52df5b84750989e34e39919ec7e59fafc4c104cc1607ab2d31"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:603e7d640e54ad764d2b4da6b61e126259af84f253a20f512dd10689566e5478"}, + {file = "bitarray-2.9.2-cp310-cp310-win32.whl", hash = "sha256:f00079f8e69d75c2a417de7961a77612bb77ef46c09bc74607d86de4740771ef"}, + {file = "bitarray-2.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:1bb33673e7f7190a65f0a940c1ef63266abdb391f4a3e544a47542d40a81f536"}, + {file = "bitarray-2.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fe71fd4b76380c2772f96f1e53a524da7063645d647a4fcd3b651bdd80ca0f2e"}, + {file = "bitarray-2.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d527172919cdea1e13994a66d9708a80c3d33dedcf2f0548e4925e600fef3a3a"}, + {file = "bitarray-2.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:052c5073bdcaa9dd10628d99d37a2f33ec09364b86dd1f6281e2d9f8d3db3060"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e064caa55a6ed493aca1eda06f8b3f689778bc780a75e6ad7724642ba5dc62f7"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:508069a04f658210fdeee85a7a0ca84db4bcc110cbb1d21f692caa13210f24a7"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4da73ebd537d75fa7bccfc2228fcaedea0803f21dd9d0bf0d3b67fef3c4af294"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cb378eaa65cd43098f11ff5d27e48ee3b956d2c00d2d6b5bfc2a09fe183be47"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d14c790b91f6cbcd9b718f88ed737c78939980c69ac8c7f03dd7e60040c12951"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7eea9318293bc0ea6447e9ebfba600a62f3428bea7e9c6d42170ae4f481dbab3"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b76ffec27c7450b8a334f967366a9ebadaea66ee43f5b530c12861b1a991f503"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:76b76a07d4ee611405045c6950a1e24c4362b6b44808d4ad6eea75e0dbc59af4"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c7d16beeaaab15b075990cd26963d6b5b22e8c5becd131781514a00b8bdd04bd"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60df43e868a615c7e15117a1e1c2e5e11f48f6457280eba6ddf8fbefbec7da99"}, + {file = "bitarray-2.9.2-cp311-cp311-win32.whl", hash = "sha256:e788608ed7767b7b3bbde6d49058bccdf94df0de9ca75d13aa99020cc7e68095"}, + {file = "bitarray-2.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:a23397da092ef0a8cfe729571da64c2fc30ac18243caa82ac7c4f965087506ff"}, + {file = "bitarray-2.9.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:90e3a281ffe3897991091b7c46fca38c2675bfd4399ffe79dfeded6c52715436"}, + {file = "bitarray-2.9.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bed637b674db5e6c8a97a4a321e3e4d73e72d50b5c6b29950008a93069cc64cd"}, + {file = "bitarray-2.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e49066d251dbbe4e6e3a5c3937d85b589e40e2669ad0eef41a00f82ec17d844b"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c4344e96642e2211fb3a50558feff682c31563a4c64529a931769d40832ca79"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aeb60962ec4813c539a59fbd4f383509c7222b62c3fb1faa76b54943a613e33a"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed0f7982f10581bb16553719e5e8f933e003f5b22f7d25a68bdb30fac630a6ff"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c71d1cabdeee0cdda4669168618f0e46b7dace207b29da7b63aaa1adc2b54081"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0ef2d0a6f1502d38d911d25609b44c6cc27bee0a4363dd295df78b075041b60"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6f71d92f533770fb027388b35b6e11988ab89242b883f48a6fe7202d238c61f8"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ba0734aa300757c924f3faf8148e1b8c247176a0ac8e16aefdf9c1eb19e868f7"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:d91406f413ccbf4af6ab5ae7bc78f772a95609f9ddd14123db36ef8c37116d95"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:87abb7f80c0a042f3fe8e5264da1a2756267450bb602110d5327b8eaff7682e7"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b558ce85579b51a2e38703877d1e93b7728a7af664dd45a34e833534f0b755d"}, + {file = "bitarray-2.9.2-cp312-cp312-win32.whl", hash = "sha256:dac2399ee2889fbdd3472bfc2ede74c34cceb1ccf29a339964281a16eb1d3188"}, + {file = "bitarray-2.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:48a30d718d1a6dfc22a49547450107abe8f4afdf2abdcbe76eb9ed88edc49498"}, + {file = "bitarray-2.9.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2c6be1b651fad8f3adb7a5aa12c65b612cd9b89530969af941844ae680f7d981"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5b399ae6ab975257ec359f03b48fc00b1c1cd109471e41903548469b8feae5c"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b3543c8a1cb286ad105f11c25d8d0f712f41c5c55f90be39f0e5a1376c7d0b0"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:03adaacb79e2fb8f483ab3a67665eec53bb3fd0cd5dbd7358741aef124688db3"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ae5b0657380d2581e13e46864d147a52c1e2bbac9f59b59c576e42fa7d10cf0"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c1f4bf6ea8eb9d7f30808c2e9894237a96650adfecbf5f3643862dc5982f89e"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a8873089be2aa15494c0f81af1209f6e1237d762c5065bc4766c1b84321e1b50"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:677e67f50e2559efc677a4366707070933ad5418b8347a603a49a070890b19bc"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:a620d8ce4ea2f1c73c6b6b1399e14cb68c6915e2be3fad5808c2998ed55b4acf"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:64115ccabbdbe279c24c367b629c6b1d3da9ed36c7420129e27c338a3971bfee"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5d6fb422772e75385b76ad1c52f45a68bd4efafd8be8d0061c11877be74c4d43"}, + {file = "bitarray-2.9.2-cp36-cp36m-win32.whl", hash = "sha256:852e202875dd6dfd6139ce7ec4e98dac2b17d8d25934dc99900831e81c3adaef"}, + {file = "bitarray-2.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:7dfefdcb0dc6a3ba9936063cec65a74595571b375beabe18742b3d91d087eefd"}, + {file = "bitarray-2.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b306c4cf66912511422060f7f5e1149c8bdb404f8e00e600561b0749fdd45659"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a09c4f81635408e3387348f415521d4b94198c562c23330f560596a6aaa26eaf"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5361413fd2ecfdf44dc8f065177dc6aba97fa80a91b815586cb388763acf7f8d"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e8a9475d415ef1eaae7942df6f780fa4dcd48fce32825eda591a17abba869299"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9b87baa7bfff9a5878fcc1bffe49ecde6e647a72a64b39a69cd8a2992a43a34"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb6b86cfdfc503e92cb71c68766a24565359136961642504a7cc9faf936d9c88"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cd56b8ae87ebc71bcacbd73615098e8a8de952ecbb5785b6b4e2b07da8a06e1f"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3fa909cfd675004aed8b4cc9df352415933656e0155a6209d878b7cb615c787e"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b069ca9bf728e0c5c5b60e00a89df9af34cc170c695c3bfa3b372d8f40288efb"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6067f2f07a7121749858c7daa93c8774325c91590b3e81a299621e347740c2ae"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:321841cdad1dd0f58fe62e80e9c9c7531f8ebf8be93f047401e930dc47425b1e"}, + {file = "bitarray-2.9.2-cp37-cp37m-win32.whl", hash = "sha256:54e16e32e60973bb83c315de9975bc1bcfc9bd50bb13001c31da159bc49b0ca1"}, + {file = "bitarray-2.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:f4dcadb7b8034aa3491ee8f5a69b3d9ba9d7d1e55c3cc1fc45be313e708277f8"}, + {file = "bitarray-2.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c8919fdbd3bb596b104388b56ae4b266eb28da1f2f7dff2e1f9334a21840fe96"}, + {file = "bitarray-2.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eb7a9d8a2e400a1026de341ad48e21670a6261a75b06df162c5c39b0d0e7c8f4"}, + {file = "bitarray-2.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6ec84668dd7b937874a2b2c293cd14ba84f37be0d196dead852e0ada9815d807"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2de9a31c34e543ae089fd2a5ced01292f725190e379921384f695e2d7184bd3"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9521f49ae121a17c0a41e5112249e6fa7f6a571245b1118de81fb86e7c1bc1ce"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6cc6545d6d76542aee3d18c1c9485fb7b9812b8df4ebe52c4535ec42081b48f"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:856bbe1616425f71c0df5ef2e8755e878d9504d5a531acba58ab4273c52c117a"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4bba8042ea6ab331ade91bc435d81ad72fddb098e49108610b0ce7780c14e68"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a035da89c959d98afc813e3c62f052690d67cfd55a36592f25d734b70de7d4b0"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6d70b1579da7fb71be5a841a1f965d19aca0ef27f629cfc07d06b09aafd0a333"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:405b83bed28efaae6d86b6ab287c75712ead0adbfab2a1075a1b7ab47dad4d62"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7eb8be687c50da0b397d5e0ab7ca200b5ebb639e79a9f5e285851d1944c94be9"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eceb551dfeaf19c609003a69a0cf8264b0efd7abc3791a11dfabf4788daf0d19"}, + {file = "bitarray-2.9.2-cp38-cp38-win32.whl", hash = "sha256:bb198c6ed1edbcdaf3d1fa3c9c9d1cdb7e179a5134ef5ee660b53cdec43b34e7"}, + {file = "bitarray-2.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:648d2f2685590b0103c67a937c2fb9e09bcc8dfb166f0c7c77bd341902a6f5b3"}, + {file = "bitarray-2.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ea816dc8f8e65841a8bbdd30e921edffeeb6f76efe6a1eb0da147b60d539d1cf"}, + {file = "bitarray-2.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4d0e32530f941c41eddfc77600ec89b65184cb909c549336463a738fab3ed285"}, + {file = "bitarray-2.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4a22266fb416a3b6c258bf7f83c9fe531ba0b755a56986a81ad69dc0f3bcc070"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc6d3e80dd8239850f2604833ff3168b28909c8a9357abfed95632cccd17e3e7"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f135e804986b12bf14f2cd1eb86674c47dea86c4c5f0fa13c88978876b97ebe6"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87580c7f7d14f7ec401eda7adac1e2a25e95153e9c339872c8ae61b3208819a1"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64b433e26993127732ac7b66a7821b2537c3044355798de7c5fcb0af34b8296f"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e497c535f2a9b68c69d36631bf2dba243e05eb343b00b9c7bbdc8c601c6802d"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e40b3cb9fa1edb4e0175d7c06345c49c7925fe93e39ef55ecb0bc40c906b0c09"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f2f8692f95c9e377eb19ca519d30d1f884b02feb7e115f798de47570a359e43f"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f0b84fc50b6dbeced4fa390688c07c10a73222810fb0e08392bd1a1b8259de36"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d656ad38c942e38a470ddbce26b5020e08e1a7ea86b8fd413bb9024b5189993a"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6ab0f1dbfe5070db98771a56aa14797595acd45a1af9eadfb193851a270e7996"}, + {file = "bitarray-2.9.2-cp39-cp39-win32.whl", hash = "sha256:0a99b23ac845a9ea3157782c97465e6ae026fe0c7c4c1ed1d88f759fd6ea52d9"}, + {file = "bitarray-2.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:9bbcfc7c279e8d74b076e514e669b683f77b4a2a328585b3f16d4c5259c91222"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:43847799461d8ba71deb4d97b47250c2c2fb66d82cd3cb8b4caf52bb97c03034"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f44381b0a4bdf64416082f4f0e7140377ae962c0ced6f983c6d7bbfc034040"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a484061616fb4b158b80789bd3cb511f399d2116525a8b29b6334c68abc2310f"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ff9e38356cc803e06134cf8ae9758e836ccd1b793135ef3db53c7c5d71e93bc"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b44105792fbdcfbda3e26ee88786790fda409da4c71f6c2b73888108cf8f062f"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7e913098de169c7fc890638ce5e171387363eb812579e637c44261460ac00aa2"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6fe315355cdfe3ed22ef355b8bdc81a805ca4d0949d921576560e5b227a1112"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f708e91fdbe443f3bec2df394ed42328fb9b0446dff5cb4199023ac6499e09fd"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b7b09489b71f9f1f64c0fa0977e250ec24500767dab7383ba9912495849cadf"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:128cc3488176145b9b137fdcf54c1c201809bbb8dd30b260ee40afe915843b43"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:21f21e7f56206be346bdbda2a6bdb2165a5e6a11821f88fd4911c5a6bbbdc7e2"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f4dd3af86dd8a617eb6464622fb64ca86e61ce99b59b5c35d8cd33f9c30603d"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6465de861aff7a2559f226b37982007417eab8c3557543879987f58b453519bd"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbaf2bb71d6027152d603f1d5f31e0dfd5e50173d06f877bec484e5396d4594b"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2f32948c86e0d230a296686db28191b67ed229756f84728847daa0c7ab7406e3"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be94e5a685e60f9d24532af8fe5c268002e9016fa80272a94727f435de3d1003"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5cc9381fd54f3c23ae1039f977bfd6d041a5c3c1518104f616643c3a5a73b15"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd926e8ae4d1ed1ac4a8f37212a62886292f692bc1739fde98013bf210c2d175"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:461a3dafb9d5fda0bb3385dc507d78b1984b49da3fe4c6d56c869a54373b7008"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:393cb27fd859af5fd9c16eb26b1c59b17b390ff66b3ae5d0dd258270191baf13"}, + {file = "bitarray-2.9.2.tar.gz", hash = "sha256:a8f286a51a32323715d77755ed959f94bef13972e9a2fe71b609e40e6d27957e"}, +] [[package]] name = "black" -version = "22.1.0" +version = "24.2.0" description = "The uncompromising code formatter." -category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.8" +files = [ + {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, + {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, + {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, + {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, + {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, + {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, + {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, + {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, + {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, + {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, + {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, + {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, + {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, + {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, + {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, + {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, + {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, + {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, + {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, + {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, + {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, + {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, +] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" +packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = ">=1.1.0" -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "cbor2" +version = "5.6.2" +description = "CBOR (de)serializer with extensive tag support" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cbor2-5.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:516b8390936bb172ff18d7b609a452eaa51991513628949b0a9bf25cbe5a7129"}, + {file = "cbor2-5.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1b8b504b590367a51fe8c0d9b8cb458a614d782d37b24483097e2b1e93ed0fff"}, + {file = "cbor2-5.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f687e6731b1198811223576800258a712ddbfdcfa86c0aee2cc8269193e6b96"}, + {file = "cbor2-5.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e94043d99fe779f62a15a5e156768588a2a7047bb3a127fa312ac1135ff5ecb"}, + {file = "cbor2-5.6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8af7162fcf7aa2649f02563bdb18b2fa6478b751eee4df0257bffe19ea8f107a"}, + {file = "cbor2-5.6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ea7ecd81c5c6e02c2635973f52a0dd1e19c0bf5ef51f813d8cd5e3e7ed072726"}, + {file = "cbor2-5.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3c7f223f1fedc74d33f363d184cb2bab9e4bdf24998f73b5e3bef366d6c41628"}, + {file = "cbor2-5.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ea9e150029c3976c46ee9870b6dcdb0a5baae21008fe3290564886b11aa2b64"}, + {file = "cbor2-5.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:922e06710e5cf6f56b82b0b90d2f356aa229b99e570994534206985f675fd307"}, + {file = "cbor2-5.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b01a718e083e6de8b43296c3ccdb3aa8af6641f6bbb3ea1700427c6af73db28a"}, + {file = "cbor2-5.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac85eb731c524d148f608b9bdb2069fa79e374a10ed5d10a2405eba9a6561e60"}, + {file = "cbor2-5.6.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03e5b68867b9d89ff2abd14ef7c6d42fbd991adc3e734a19a294935f22a4d05a"}, + {file = "cbor2-5.6.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7221b83000ee01d674572eec1d1caa366eac109d1d32c14d7af9a4aaaf496563"}, + {file = "cbor2-5.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:9aca73b63bdc6561e1a0d38618e78b9c204c942260d51e663c92c4ba6c961684"}, + {file = "cbor2-5.6.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:377cfe9d5560c682486faef6d856226abf8b2801d95fa29d4e5d75b1615eb091"}, + {file = "cbor2-5.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fdc564ef2e9228bcd96ec8c6cdaa431a48ab03b3fb8326ead4b3f986330e5b9e"}, + {file = "cbor2-5.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d1c0021d9a1f673066de7c8941f71a59abb11909cc355892dda01e79a2b3045"}, + {file = "cbor2-5.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fde9e704e96751e0729cc58b912d0e77c34387fb6bcceea0817069e8683df45"}, + {file = "cbor2-5.6.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:30e9ba8f4896726ca61869efacda50b6859aff92162ae5a0e192859664f36c81"}, + {file = "cbor2-5.6.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a1e18e65ac71e04434ff5b58bde5c53f85b9c5bc92a3c0e2265089d3034f3"}, + {file = "cbor2-5.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:94981277b4bf448a2754c1f34a9d0055a9d1c5a8d102c933ffe95c80f1085bae"}, + {file = "cbor2-5.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f70db0ebcf005c25408e8d5cc4b9558c899f13a3e2f8281fa3d3be4894e0e821"}, + {file = "cbor2-5.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:22c24fe9ef1696a84b8fd80ff66eb0e5234505d8b9a9711fc6db57bce10771f3"}, + {file = "cbor2-5.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a4a3420f80d6b942874d66eaad07658066370df994ddee4125b48b2cbc61ece"}, + {file = "cbor2-5.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b28d8ff0e726224a7429281700c28afe0e665f83f9ae79648cbae3f1a391cbf"}, + {file = "cbor2-5.6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c10ede9462458998f1b9c488e25fe3763aa2491119b7af472b72bf538d789e24"}, + {file = "cbor2-5.6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ea686dfb5e54d690e704ce04993bc8ca0052a7cd2d4b13dd333a41cca8a05a05"}, + {file = "cbor2-5.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:22996159b491d545ecfd489392d3c71e5d0afb9a202dfc0edc8b2cf413a58326"}, + {file = "cbor2-5.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9faa0712d414a88cc1244c78cd4b28fced44f1827dbd8c1649e3c40588aa670f"}, + {file = "cbor2-5.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6031a284d93fc953fc2a2918f261c4f5100905bd064ca3b46961643e7312a828"}, + {file = "cbor2-5.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30c8a9a9df79f26e72d8d5fa51ef08eb250d9869a711bcf9539f1865916c983"}, + {file = "cbor2-5.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44bf7457fca23209e14dab8181dff82466a83b72e55b444dbbfe90fa67659492"}, + {file = "cbor2-5.6.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cc29c068687aa2e7778f63b653f1346065b858427a2555df4dc2191f4a0de8ce"}, + {file = "cbor2-5.6.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:42eaf0f768bd27afcb38135d5bfc361d3a157f1f5c7dddcd8d391f7fa43d9de8"}, + {file = "cbor2-5.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:8839b73befa010358477736680657b9d08c1ed935fd973decb1909712a41afdc"}, + {file = "cbor2-5.6.2-py3-none-any.whl", hash = "sha256:c0b53a65673550fde483724ff683753f49462d392d45d7b6576364b39e76e54c"}, + {file = "cbor2-5.6.2.tar.gz", hash = "sha256:b7513c2dea8868991fad7ef8899890ebcf8b199b9b4461c3c11d7ad3aef4820d"}, +] + +[package.extras] +benchmarks = ["pytest-benchmark (==4.0.0)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.3.0)", "typing-extensions"] +test = ["coverage (>=7)", "hypothesis", "pytest"] + [[package]] name = "certifi" -version = "2021.10.8" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] [[package]] name = "charset-normalizer" -version = "2.0.11" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false -python-versions = ">=3.5.0" - -[package.extras] -unicode_backport = ["unicodedata2"] +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] [[package]] name = "click" -version = "8.0.3" +version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "crytic-compile" +version = "0.3.7" +description = "Util to facilitate smart contracts compilation." +optional = false +python-versions = "!=3.12.0,>=3.8" +files = [ + {file = "crytic-compile-0.3.7.tar.gz", hash = "sha256:c7713d924544934d063e68313da8d588a3ad82cd4f40eae30d99f2dd6e640d4b"}, + {file = "crytic_compile-0.3.7-py3-none-any.whl", hash = "sha256:bd8fc87f89afea5db714df13e302dcbaf50dd7c806fa424ace661384aa60634b"}, +] + +[package.dependencies] +cbor2 = "*" +pycryptodome = ">=3.4.6" +solc-select = ">=v1.0.4" + +[package.extras] +dev = ["crytic-compile[doc,lint,test]"] +doc = ["pdoc"] +lint = ["black (==22.3.0)", "darglint (==1.8.0)", "mypy (==0.942)", "pylint (==2.13.4)"] +test = ["pytest", "pytest-cov"] [[package]] name = "cytoolz" -version = "0.11.2" +version = "0.12.3" description = "Cython implementation of Toolz: High performance functional utilities" -category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" +files = [ + {file = "cytoolz-0.12.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bbe58e26c84b163beba0fbeacf6b065feabc8f75c6d3fe305550d33f24a2d346"}, + {file = "cytoolz-0.12.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c51b66ada9bfdb88cf711bf350fcc46f82b83a4683cf2413e633c31a64df6201"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e70d9c615e5c9dc10d279d1e32e846085fe1fd6f08d623ddd059a92861f4e3dd"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a83f4532707963ae1a5108e51fdfe1278cc8724e3301fee48b9e73e1316de64f"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d028044524ee2e815f36210a793c414551b689d4f4eda28f8bbb0883ad78bf5f"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c2875bcd1397d0627a09a4f9172fa513185ad302c63758efc15b8eb33cc2a98"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:131ff4820e5d64a25d7ad3c3556f2d8aa65c66b3f021b03f8a8e98e4180dd808"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:04afa90d9d9d18394c40d9bed48c51433d08b57c042e0e50c8c0f9799735dcbd"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dc1ca9c610425f9854323669a671fc163300b873731584e258975adf50931164"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bfa3f8e01bc423a933f2e1c510cbb0632c6787865b5242857cc955cae220d1bf"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:f702e295dddef5f8af4a456db93f114539b8dc2a7a9bc4de7c7e41d169aa6ec3"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0fbad1fb9bb47e827d00e01992a099b0ba79facf5e5aa453be066033232ac4b5"}, + {file = "cytoolz-0.12.3-cp310-cp310-win32.whl", hash = "sha256:8587c3c3dbe78af90c5025288766ac10dc2240c1e76eb0a93a4e244c265ccefd"}, + {file = "cytoolz-0.12.3-cp310-cp310-win_amd64.whl", hash = "sha256:9e45803d9e75ef90a2f859ef8f7f77614730f4a8ce1b9244375734567299d239"}, + {file = "cytoolz-0.12.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ac4f2fb38bbc67ff1875b7d2f0f162a247f43bd28eb7c9d15e6175a982e558d"}, + {file = "cytoolz-0.12.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0cf1e1e96dd86829a0539baf514a9c8473a58fbb415f92401a68e8e52a34ecd5"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08a438701c6141dd34eaf92e9e9a1f66e23a22f7840ef8a371eba274477de85d"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6b6f11b0d7ed91be53166aeef2a23a799e636625675bb30818f47f41ad31821"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fde09384d23048a7b4ac889063761e44b89a0b64015393e2d1d21d5c1f534a"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d3bfe45173cc8e6c76206be3a916d8bfd2214fb2965563e288088012f1dabfc"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27513a5d5b6624372d63313574381d3217a66e7a2626b056c695179623a5cb1a"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d294e5e81ff094fe920fd545052ff30838ea49f9e91227a55ecd9f3ca19774a0"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:727b01a2004ddb513496507a695e19b5c0cfebcdfcc68349d3efd92a1c297bf4"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:fe1e1779a39dbe83f13886d2b4b02f8c4b10755e3c8d9a89b630395f49f4f406"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:de74ef266e2679c3bf8b5fc20cee4fc0271ba13ae0d9097b1491c7a9bcadb389"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e04d22049233394e0b08193aca9737200b4a2afa28659d957327aa780ddddf2"}, + {file = "cytoolz-0.12.3-cp311-cp311-win32.whl", hash = "sha256:20d36430d8ac809186736fda735ee7d595b6242bdb35f69b598ef809ebfa5605"}, + {file = "cytoolz-0.12.3-cp311-cp311-win_amd64.whl", hash = "sha256:780c06110f383344d537f48d9010d79fa4f75070d214fc47f389357dd4f010b6"}, + {file = "cytoolz-0.12.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:86923d823bd19ce35805953b018d436f6b862edd6a7c8b747a13d52b39ed5716"}, + {file = "cytoolz-0.12.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3e61acfd029bfb81c2c596249b508dfd2b4f72e31b7b53b62e5fb0507dd7293"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd728f4e6051af6af234651df49319da1d813f47894d4c3c8ab7455e01703a37"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe8c6267caa7ec67bcc37e360f0d8a26bc3bdce510b15b97f2f2e0143bdd3673"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99462abd8323c52204a2a0ce62454ce8fa0f4e94b9af397945c12830de73f27e"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da125221b1fa25c690fcd030a54344cecec80074df018d906fc6a99f46c1e3a6"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c18e351956f70db9e2d04ff02f28e9a41839250d3f936a4c8a1eabd1c3094d2"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:921e6d2440ac758c4945c587b1d1d9b781b72737ac0c0ca5d5e02ca1db8bded2"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1651a9bd591a8326329ce1d6336f3129161a36d7061a4d5ea9e5377e033364cf"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8893223b87c2782bd59f9c4bd5c7bf733edd8728b523c93efb91d7468b486528"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:e4d2961644153c5ae186db964aa9f6109da81b12df0f1d3494b4e5cf2c332ee2"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:71b6eb97f6695f7ba8ce69c49b707a351c5f46fd97f5aeb5f6f2fb0d6e72b887"}, + {file = "cytoolz-0.12.3-cp312-cp312-win32.whl", hash = "sha256:cee3de65584e915053412cd178729ff510ad5f8f585c21c5890e91028283518f"}, + {file = "cytoolz-0.12.3-cp312-cp312-win_amd64.whl", hash = "sha256:9eef0d23035fa4dcfa21e570961e86c375153a7ee605cdd11a8b088c24f707f6"}, + {file = "cytoolz-0.12.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9a38332cfad2a91e89405b7c18b3f00e2edc951c225accbc217597d3e4e9fde"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f501ae1353071fa5d6677437bbeb1aeb5622067dce0977cedc2c5ec5843b202"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56f899758146a52e2f8cfb3fb6f4ca19c1e5814178c3d584de35f9e4d7166d91"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:800f0526adf9e53d3c6acda748f4def1f048adaa780752f154da5cf22aa488a2"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0976a3fcb81d065473173e9005848218ce03ddb2ec7d40dd6a8d2dba7f1c3ae"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c835eab01466cb67d0ce6290601ebef2d82d8d0d0a285ed0d6e46989e4a7a71a"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4fba0616fcd487e34b8beec1ad9911d192c62e758baa12fcb44448b9b6feae22"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6f6e8207d732651e0204779e1ba5a4925c93081834570411f959b80681f8d333"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:8119bf5961091cfe644784d0bae214e273b3b3a479f93ee3baab97bbd995ccfe"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7ad1331cb68afeec58469c31d944a2100cee14eac221553f0d5218ace1a0b25d"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:92c53d508fb8a4463acc85b322fa24734efdc66933a5c8661bdc862103a3373d"}, + {file = "cytoolz-0.12.3-cp37-cp37m-win32.whl", hash = "sha256:2c6dd75dae3d84fa8988861ab8b1189d2488cb8a9b8653828f9cd6126b5e7abd"}, + {file = "cytoolz-0.12.3-cp37-cp37m-win_amd64.whl", hash = "sha256:caf07a97b5220e6334dd32c8b6d8b2bd255ca694eca5dfe914bb5b880ee66cdb"}, + {file = "cytoolz-0.12.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed0cfb9326747759e2ad81cb6e45f20086a273b67ac3a4c00b19efcbab007c60"}, + {file = "cytoolz-0.12.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:96a5a0292575c3697121f97cc605baf2fd125120c7dcdf39edd1a135798482ca"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b76f2f50a789c44d6fd7f773ec43d2a8686781cd52236da03f7f7d7998989bee"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2905fdccacc64b4beba37f95cab9d792289c80f4d70830b70de2fc66c007ec01"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ebe23028eac51251f22ba01dba6587d30aa9c320372ca0c14eeab67118ec3f"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96c715404a3825e37fe3966fe84c5f8a1f036e7640b2a02dbed96cac0c933451"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bac0adffc1b6b6a4c5f1fd1dd2161afb720bcc771a91016dc6bdba59af0a5d3"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:37441bf4a2a4e2e0fe9c3b0ea5e72db352f5cca03903977ffc42f6f6c5467be9"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f04037302049cb30033f7fa4e1d0e44afe35ed6bfcf9b380fc11f2a27d3ed697"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f37b60e66378e7a116931d7220f5352186abfcc950d64856038aa2c01944929c"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ec9be3e4b6f86ea8b294d34c990c99d2ba6c526ef1e8f46f1d52c263d4f32cd7"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0e9199c9e3fbf380a92b8042c677eb9e7ed4bccb126de5e9c0d26f5888d96788"}, + {file = "cytoolz-0.12.3-cp38-cp38-win32.whl", hash = "sha256:18cd61e078bd6bffe088e40f1ed02001387c29174750abce79499d26fa57f5eb"}, + {file = "cytoolz-0.12.3-cp38-cp38-win_amd64.whl", hash = "sha256:765b8381d4003ceb1a07896a854eee2c31ebc950a4ae17d1e7a17c2a8feb2a68"}, + {file = "cytoolz-0.12.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b4a52dd2a36b0a91f7aa50ca6c8509057acc481a24255f6cb07b15d339a34e0f"}, + {file = "cytoolz-0.12.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:581f1ce479769fe7eeb9ae6d87eadb230df8c7c5fff32138162cdd99d7fb8fc3"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46f505d4c6eb79585c8ad0b9dc140ef30a138c880e4e3b40230d642690e36366"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59276021619b432a5c21c01cda8320b9cc7dbc40351ffc478b440bfccd5bbdd3"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e44f4c25e1e7cf6149b499c74945a14649c8866d36371a2c2d2164e4649e7755"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c64f8e60c1dd69e4d5e615481f2d57937746f4a6be2d0f86e9e7e3b9e2243b5e"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33c63186f3bf9d7ef1347bc0537bb9a0b4111a0d7d6e619623cabc18fef0dc3b"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fdddb9d988405f24035234f1e8d1653ab2e48cc2404226d21b49a129aefd1d25"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6986632d8a969ea1e720990c818dace1a24c11015fd7c59b9fea0b65ef71f726"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0ba1cbc4d9cd7571c917f88f4a069568e5121646eb5d82b2393b2cf84712cf2a"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7d267ffc9a36c0a9a58c7e0adc9fa82620f22e4a72533e15dd1361f57fc9accf"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95e878868a172a41fbf6c505a4b967309e6870e22adc7b1c3b19653d062711fa"}, + {file = "cytoolz-0.12.3-cp39-cp39-win32.whl", hash = "sha256:8e21932d6d260996f7109f2a40b2586070cb0a0cf1d65781e156326d5ebcc329"}, + {file = "cytoolz-0.12.3-cp39-cp39-win_amd64.whl", hash = "sha256:0d8edfbc694af6c9bda4db56643fb8ed3d14e47bec358c2f1417de9a12d6d1fb"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:55f9bd1ae6c2a27eda5abe2a0b65a83029d2385c5a1da7b8ef47af5905d7e905"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2d271393c378282727f1231d40391ae93b93ddc0997448acc21dd0cb6a1e56d"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee98968d6a66ee83a8ceabf31182189ab5d8598998c8ce69b6d5843daeb2db60"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01cfb8518828c1189200c02a5010ea404407fb18fd5589e29c126e84bbeadd36"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:456395d7aec01db32bf9e6db191d667347c78d8d48e77234521fa1078f60dabb"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cd88028bb897fba99ddd84f253ca6bef73ecb7bdf3f3cf25bc493f8f97d3c7c5"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59b19223e7f7bd7a73ec3aa6fdfb73b579ff09c2bc0b7d26857eec2d01a58c76"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a79d72b08048a0980a59457c239555f111ac0c8bdc140c91a025f124104dbb4"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dd70141b32b717696a72b8876e86bc9c6f8eff995c1808e299db3541213ff82"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a1445c91009eb775d479e88954c51d0b4cf9a1e8ce3c503c2672d17252882647"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ca6a9a9300d5bda417d9090107c6d2b007683efc59d63cc09aca0e7930a08a85"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be6feb903d2a08a4ba2e70e950e862fd3be9be9a588b7c38cee4728150a52918"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b6f43f086e5a965d33d62a145ae121b4ccb6e0789ac0acc895ce084fec8c65"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:534fa66db8564d9b13872d81d54b6b09ae592c585eb826aac235bd6f1830f8ad"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:fea649f979def23150680de1bd1d09682da3b54932800a0f90f29fc2a6c98ba8"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a447247ed312dd64e3a8d9483841ecc5338ee26d6e6fbd29cd373ed030db0240"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba3f843aa89f35467b38c398ae5b980a824fdbdb94065adc6ec7c47a0a22f4c7"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:582c22f97a380211fb36a7b65b1beeb84ea11d82015fa84b054be78580390082"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47feb089506fc66e1593cd9ade3945693a9d089a445fbe9a11385cab200b9f22"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ba9002d2f043943744a9dc8e50a47362bcb6e6f360dc0a1abcb19642584d87bb"}, + {file = "cytoolz-0.12.3.tar.gz", hash = "sha256:4503dc59f4ced53a54643272c61dc305d1dbbfbd7d6bdf296948de9f34c3a282"}, +] [package.dependencies] toolz = ">=0.8.0" @@ -170,339 +676,462 @@ cython = ["cython"] name = "dataclassy" version = "0.11.1" description = "A fast and flexible reimplementation of data classes" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "dataclassy-0.11.1-py3-none-any.whl", hash = "sha256:bcb030d3d700cf9b1597042bbc8375b92773e6f68f65675a7071862c0ddb87f5"}, + {file = "dataclassy-0.11.1.tar.gz", hash = "sha256:ad6622cb91e644d13f68768558983fbc22c90a8ff7e355638485d18b9baf1198"}, +] [[package]] name = "eip712" -version = "0.1.0" +version = "0.2.4" description = "eip712: Message classes for typed structured data hashing and signing in Ethereum" -category = "main" optional = false -python-versions = ">=3.6,<4" +python-versions = ">=3.8,<4" +files = [ + {file = "eip712-0.2.4-py3-none-any.whl", hash = "sha256:19d9abdb4b0ffb97f12a68addc2bbcdb2f0a2da17bc038a22c77b42353de1ecd"}, + {file = "eip712-0.2.4.tar.gz", hash = "sha256:e69760414523f60328279620776549a17ff72f89974688710d3467ae08717070"}, +] [package.dependencies] -dataclassy = ">=0.8.2,<1.0" -eth-abi = ">=2.0.0b7,<3" -eth-typing = ">=2.2,<3.0" -eth-utils = ">=1.3.0,<2" -hexbytes = "<0.3.0" -pycryptodome = ">=3.4.7,<4.0.0" +dataclassy = ">=0.8.2,<1" +eth-abi = ">=4.2.1,<6" +eth-account = ">=0.10.0,<0.11" +eth-hash = {version = "*", extras = ["pycryptodome"]} +eth-typing = ">=3.5.2,<4" +eth-utils = ">=2.3.1,<3" +hexbytes = ">=0.3.0,<1" [package.extras] -dev = ["pytest (>=6.0,<7.0)", "pytest-xdist", "pytest-cov", "hypothesis (>=6.2.0,<7.0)", "black (>=20.8b1,<21.0)", "mypy (>=0.800,<1.0)", "flake8 (>=3.8.3,<4.0)", "isort (>=5.7.0,<6.0)", "Sphinx (>=3.4.3,<4)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)", "setuptools", "setuptools-scm", "wheel", "twine", "commitizen", "pytest-watch", "ipython", "ipdb"] -doc = ["Sphinx (>=3.4.3,<4)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -lint = ["black (>=20.8b1,<21.0)", "mypy (>=0.800,<1.0)", "flake8 (>=3.8.3,<4.0)", "isort (>=5.7.0,<6.0)"] -release = ["setuptools", "setuptools-scm", "wheel", "twine"] -test = ["pytest (>=6.0,<7.0)", "pytest-xdist", "pytest-cov", "hypothesis (>=6.2.0,<7.0)"] +dev = ["IPython", "Sphinx (>=5.3.0,<6)", "black (>=23.12.0,<24)", "commitizen (>=2.42,<3)", "flake8 (>=6.1.0,<7)", "hypothesis (>=6.70.0,<7)", "ipdb", "isort (>=5.12.0,<6)", "mdformat (>=0.7.17,<0.8)", "mdformat-frontmatter (>=0.4.1,<0.5)", "mdformat-gfm (>=0.3.5,<0.4)", "mypy (>=1.7.1,<2)", "myst-parser (>=0.18.1,<0.19)", "pre-commit", "pytest (>=6.0,<8)", "pytest-cov", "pytest-watch", "pytest-xdist", "setuptools", "sphinx-rtd-theme (>=1.2.0,<2)", "sphinxcontrib-napoleon (>=0.7)", "twine", "types-setuptools", "wheel"] +doc = ["Sphinx (>=5.3.0,<6)", "myst-parser (>=0.18.1,<0.19)", "sphinx-rtd-theme (>=1.2.0,<2)", "sphinxcontrib-napoleon (>=0.7)"] +lint = ["black (>=23.12.0,<24)", "flake8 (>=6.1.0,<7)", "isort (>=5.12.0,<6)", "mdformat (>=0.7.17,<0.8)", "mdformat-frontmatter (>=0.4.1,<0.5)", "mdformat-gfm (>=0.3.5,<0.4)", "mypy (>=1.7.1,<2)", "types-setuptools"] +release = ["setuptools", "twine", "wheel"] +test = ["hypothesis (>=6.70.0,<7)", "pytest (>=6.0,<8)", "pytest-cov", "pytest-xdist"] [[package]] name = "eth-abi" -version = "2.1.1" +version = "5.0.0" description = "eth_abi: Python utilities for working with Ethereum ABI definitions, especially encoding and decoding" -category = "main" optional = false -python-versions = ">=3.6, <4" +python-versions = ">=3.8, <4" +files = [ + {file = "eth_abi-5.0.0-py3-none-any.whl", hash = "sha256:936a715d7366ac13cac665cbdaf01cc4aabbe8c2d810d716287a9634f9665e01"}, + {file = "eth_abi-5.0.0.tar.gz", hash = "sha256:89c4454d794d9ed92ad5cb2794698c5cee6b7b3ca6009187d0e282adc7f9b6dc"}, +] [package.dependencies] -eth-typing = ">=2.0.0,<3.0.0" -eth-utils = ">=1.2.0,<2.0.0" -parsimonious = ">=0.8.0,<0.9.0" +eth-typing = ">=3.0.0" +eth-utils = ">=2.0.0" +parsimonious = ">=0.9.0,<0.10.0" [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "pytest (==4.4.1)", "pytest-pythonpath (>=0.7.1)", "pytest-xdist (==1.22.3)", "tox (>=2.9.1,<3)", "eth-hash", "hypothesis (>=3.6.1,<4)", "flake8 (==3.4.1)", "isort (>=4.2.15,<5)", "mypy (==0.701)", "pydocstyle (>=3.0.0,<4)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.4.1)", "isort (>=4.2.15,<5)", "mypy (==0.701)", "pydocstyle (>=3.0.0,<4)"] -test = ["pytest (==4.4.1)", "pytest-pythonpath (>=0.7.1)", "pytest-xdist (==1.22.3)", "tox (>=2.9.1,<3)", "eth-hash", "hypothesis (>=3.6.1,<4)"] -tools = ["hypothesis (>=3.6.1,<4)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash[pycryptodome]", "hypothesis (>=4.18.2,<5.0.0)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-pythonpath (>=0.7.1)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +test = ["eth-hash[pycryptodome]", "hypothesis (>=4.18.2,<5.0.0)", "pytest (>=7.0.0)", "pytest-pythonpath (>=0.7.1)", "pytest-xdist (>=2.4.0)"] +tools = ["hypothesis (>=4.18.2,<5.0.0)"] [[package]] name = "eth-account" -version = "0.5.7" +version = "0.10.0" description = "eth-account: Sign Ethereum transactions and messages with local private keys" -category = "main" optional = false -python-versions = ">=3.6, <4" +python-versions = ">=3.7, <4" +files = [ + {file = "eth-account-0.10.0.tar.gz", hash = "sha256:474a2fccf7286230cf66502565f03b536921d7e1fdfceba198e42160e5ac4bc1"}, + {file = "eth_account-0.10.0-py3-none-any.whl", hash = "sha256:b7a83f506a8edf57926569e5f04471ce3f1700e572d3421b4ad0dad7a26c0978"}, +] [package.dependencies] -bitarray = ">=1.2.1,<1.3.0" -eth-abi = ">=2.0.0b7,<3" -eth-keyfile = ">=0.5.0,<0.6.0" -eth-keys = ">=0.3.4,<0.4.0" -eth-rlp = ">=0.1.2,<2" -eth-utils = ">=1.3.0,<2" -hexbytes = ">=0.1.0,<1" -rlp = ">=1.0.0,<3" +bitarray = ">=2.4.0" +eth-abi = ">=4.0.0-b.2" +eth-keyfile = ">=0.6.0" +eth-keys = ">=0.4.0" +eth-rlp = ">=0.3.0" +eth-utils = ">=2.0.0" +hexbytes = ">=0.1.0,<0.4.0" +rlp = ">=1.0.0" [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)"] -test = ["hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)"] +dev = ["black (>=23)", "build (>=0.9.0)", "bumpversion (>=0.5.3)", "coverage", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "hypothesis (>=4.18.0,<5)", "ipython", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=6.0.0)", "pytest (>=7.0.0)", "pytest-watch (>=4.1.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +doc = ["sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +lint = ["black (>=23)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=6.0.0)"] +test = ["coverage", "hypothesis (>=4.18.0,<5)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-brownie" -version = "1.18.1" +version = "1.20.2" description = "A Python framework for Ethereum smart contract deployment, testing and interaction." -category = "main" optional = false -python-versions = ">=3.7,<4" +python-versions = ">=3.10,<4" +files = [ + {file = "eth-brownie-1.20.2.tar.gz", hash = "sha256:7d9e2e1eccbc24d1a212acf345810298ed088b1bebea449ab65fd8a95b3f847e"}, + {file = "eth_brownie-1.20.2-py3-none-any.whl", hash = "sha256:5f280fad032e83ee5b76ada80934d1bf5d8a8b2b4aa3ecf80bbcb82f986c0477"}, +] [package.dependencies] -aiohttp = "3.8.1" -aiosignal = "1.2.0" -asttokens = "2.0.5" -async-timeout = "4.0.2" -attrs = "21.4.0" -base58 = "2.1.1" -bitarray = "1.2.2" -black = "22.1.0" -certifi = "2021.10.8" -charset-normalizer = "2.0.11" -click = "8.0.3" -cytoolz = "0.11.2" +aiohttp = "3.9.3" +aiosignal = "1.3.1" +asttokens = "2.4.1" +attrs = "23.2.0" +bitarray = "2.9.2" +black = "24.2.0" +cbor2 = "5.6.2" +certifi = "2024.2.2" +charset-normalizer = "3.3.2" +click = "8.1.7" +cytoolz = "0.12.3" dataclassy = "0.11.1" -eip712 = "0.1.0" -eth-abi = "2.1.1" -eth-account = "0.5.7" -eth-event = "1.2.3" -eth-hash = {version = "0.3.2", extras = ["pycryptodome"]} -eth-keyfile = "0.5.1" -eth-keys = "0.3.4" -eth-rlp = "0.2.1" -eth-typing = "2.3.0" -eth-utils = "1.10.0" -execnet = "1.9.0" -frozenlist = "1.3.0" -hexbytes = "0.2.2" +eip712 = "0.2.4" +eth-abi = "5.0.0" +eth-account = "0.10.0" +eth-event = "1.2.5" +eth-hash = {version = "0.6.0", extras = ["pycryptodome"]} +eth-keyfile = "0.7.0" +eth-keys = "0.5.0" +eth-rlp = "1.0.1" +eth-typing = "3.5.2" +eth-utils = "2.3.1" +execnet = "2.0.2" +frozenlist = "1.4.1" +hexbytes = "0.3.1" hypothesis = "6.27.3" -idna = "3.3" -inflection = "0.5.0" -iniconfig = "1.1.1" -ipfshttpclient = "0.8.0a2" -jsonschema = "3.2.0" -lazy-object-proxy = "1.7.1" -lru-dict = "1.1.7" -multiaddr = "0.0.9" -multidict = "6.0.2" -mypy-extensions = "0.4.3" -mythx-models = "1.9.1" -netaddr = "0.8.0" -packaging = "21.3" -parsimonious = "0.8.1" -pathspec = "0.9.0" -platformdirs = "2.4.1" -pluggy = "1.0.0" -prompt-toolkit = "3.0.26" -protobuf = "3.19.4" -psutil = "5.9.0" +idna = "3.6" +importlib-metadata = "7.0.1" +iniconfig = "2.0.0" +jsonschema = "4.21.1" +jsonschema-specifications = "2023.12.1" +lazy-object-proxy = "1.10.0" +lru-dict = "1.2.0" +multidict = "6.0.5" +mypy-extensions = "1.0.0" +packaging = "23.2" +parsimonious = "0.9.0" +pathspec = "0.12.1" +platformdirs = "4.2.0" +pluggy = "1.4.0" +prompt-toolkit = "3.0.43" +protobuf = "4.25.3" +psutil = "5.9.8" py = "1.11.0" -py-solc-ast = "1.2.9" +py-solc-ast = "1.2.10" py-solc-x = "1.1.1" -pycryptodome = "3.14.1" -pygments = "2.11.2" +pycryptodome = "3.20.0" +pygments = "2.17.2" pygments-lexer-solidity = "0.7.0" -pyjwt = "1.7.1" -pyparsing = "3.0.7" -pyrsistent = "0.18.1" pytest = "6.2.5" -pytest-forked = "1.4.0" +pytest-forked = "1.6.0" pytest-xdist = "1.34.0" -python-dateutil = "2.8.1" python-dotenv = "0.16.0" -pythx = "1.6.1" -pyyaml = "5.4.1" -requests = "2.27.1" -rlp = "2.0.1" -semantic-version = "2.8.5" +pyunormalize = "15.1.0" +pyyaml = "6.0.1" +referencing = "0.33.0" +regex = "2023.12.25" +requests = "2.31.0" +rlp = "4.0.0" +rpds-py = "0.18.0" +semantic-version = "2.10.0" six = "1.16.0" sortedcontainers = "2.4.0" toml = "0.10.2" -tomli = "2.0.0" -toolz = "0.11.2" -tqdm = "4.62.3" -typing-extensions = "4.0.1" -urllib3 = "1.26.8" -varint = "1.0.2" +toolz = "0.12.1" +tqdm = "4.66.2" +typing-extensions = "4.9.0" +urllib3 = "2.2.1" vvm = "0.1.0" -vyper = "0.3.1" -wcwidth = "0.2.5" -web3 = "5.27.0" -websockets = "9.1" -wrapt = "1.13.3" -yarl = "1.7.2" +vyper = "0.3.10" +wcwidth = "0.2.13" +web3 = "6.15.1" +websockets = "12.0" +wheel = "0.42.0" +wrapt = "1.16.0" +yarl = "1.9.4" +zipp = "3.17.0" [[package]] name = "eth-event" -version = "1.2.3" +version = "1.2.5" description = "Ethereum event decoder and topic generator" -category = "main" optional = false python-versions = ">=3.6, <4" +files = [ + {file = "eth-event-1.2.5.tar.gz", hash = "sha256:b733447fbdefd35a3f3deeddb78eae9362246bcbfb19075952cc592803b29586"}, + {file = "eth_event-1.2.5-py3-none-any.whl", hash = "sha256:4572adf97d301b72061684ef0b252e659a9968d29705297a25eadc2784e636ac"}, +] [package.dependencies] -eth-abi = ">=2.0.0,<3.0.0" +eth-abi = ">=4,<6" eth-hash = {version = ">=0.2.0,<1.0.0", extras = ["pycryptodome"]} -eth-utils = ">=1.2.0,<2.0.0" -hexbytes = ">=0.2.0,<1.0.0" +eth-utils = ">=2,<4" +hexbytes = "<1" [[package]] name = "eth-hash" -version = "0.3.2" +version = "0.6.0" description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (erroneously) called sha3" -category = "main" optional = false -python-versions = ">=3.5, <4" +python-versions = ">=3.8, <4" +files = [ + {file = "eth-hash-0.6.0.tar.gz", hash = "sha256:ae72889e60db6acbb3872c288cfa02ed157f4c27630fcd7f9c8442302c31e478"}, + {file = "eth_hash-0.6.0-py3-none-any.whl", hash = "sha256:9f8daaa345764f8871dc461855049ac54ae4291d780279bce6fce7f24e3f17d3"}, +] [package.dependencies] pycryptodome = {version = ">=3.6.6,<4", optional = true, markers = "extra == \"pycryptodome\""} [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] pycryptodome = ["pycryptodome (>=3.6.6,<4)"] -pysha3 = ["pysha3 (>=1.0.0,<2.0.0)"] -test = ["pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)"] +pysha3 = ["pysha3 (>=1.0.0,<2.0.0)", "safe-pysha3 (>=1.0.0)"] +test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-keyfile" -version = "0.5.1" -description = "A library for handling the encrypted keyfiles used to store ethereum private keys." -category = "main" +version = "0.7.0" +description = "eth-keyfile: A library for handling the encrypted keyfiles used to store ethereum private keys" optional = false -python-versions = "*" +python-versions = ">=3.8, <4" +files = [ + {file = "eth-keyfile-0.7.0.tar.gz", hash = "sha256:6bdb8110c3a50439deb68a04c93c9d5ddd5402353bfae1bf4cfca1d6dff14fcf"}, + {file = "eth_keyfile-0.7.0-py3-none-any.whl", hash = "sha256:6a89b231a2fe250c3a8f924f2695bb9cce33ddd0d6f7ebbcdacd183d7f83d537"}, +] [package.dependencies] -cytoolz = ">=0.9.0,<1.0.0" -eth-keys = ">=0.1.0-beta.4,<1.0.0" -eth-utils = ">=1.0.0-beta.1,<2.0.0" -pycryptodome = ">=3.4.7,<4.0.0" +eth-keys = ">=0.4.0" +eth-utils = ">=2" +pycryptodome = ">=3.6.6,<4" + +[package.extras] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["towncrier (>=21,<22)"] +test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-keys" -version = "0.3.4" -description = "Common API for Ethereum key operations." -category = "main" +version = "0.5.0" +description = "eth-keys: Common API for Ethereum key operations" optional = false -python-versions = "*" +python-versions = ">=3.8, <4" +files = [ + {file = "eth-keys-0.5.0.tar.gz", hash = "sha256:a0abccb83f3d84322591a2c047a1e3aa52ea86b185fa3e82ce311d120ca2791e"}, + {file = "eth_keys-0.5.0-py3-none-any.whl", hash = "sha256:b2bed3ff3bcede68cc0cd4458c7147baaeaac1211a1efdb6ca019f9d3d989f2b"}, +] [package.dependencies] -eth-typing = ">=2.2.1,<3.0.0" -eth-utils = ">=1.8.2,<2.0.0" +eth-typing = ">=3" +eth-utils = ">=2" [package.extras] -coincurve = ["coincurve (>=7.0.0,<13.0.0)"] -dev = ["tox (==3.20.0)", "bumpversion (==0.5.3)", "twine", "eth-utils (>=1.8.2,<2.0.0)", "eth-typing (>=2.2.1,<3.0.0)", "flake8 (==3.0.4)", "mypy (==0.782)", "asn1tools (>=0.146.2,<0.147)", "factory-boy (>=3.0.1,<3.1)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==5.4.1)", "hypothesis (>=5.10.3,<6.0.0)", "eth-hash", "eth-hash"] -eth-keys = ["eth-utils (>=1.8.2,<2.0.0)", "eth-typing (>=2.2.1,<3.0.0)"] -lint = ["flake8 (==3.0.4)", "mypy (==0.782)"] -test = ["asn1tools (>=0.146.2,<0.147)", "factory-boy (>=3.0.1,<3.1)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==5.4.1)", "hypothesis (>=5.10.3,<6.0.0)", "eth-hash", "eth-hash"] +coincurve = ["coincurve (>=12.0.0)"] +dev = ["asn1tools (>=0.146.2)", "build (>=0.9.0)", "bumpversion (>=0.5.3)", "coincurve (>=12.0.0)", "eth-hash[pysha3]", "factory-boy (>=3.0.1)", "hypothesis (>=5.10.3,<6)", "ipython", "pre-commit (>=3.4.0)", "pyasn1 (>=0.4.5)", "pytest (>=7.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["towncrier (>=21,<22)"] +test = ["asn1tools (>=0.146.2)", "eth-hash[pysha3]", "factory-boy (>=3.0.1)", "hypothesis (>=5.10.3,<6)", "pyasn1 (>=0.4.5)", "pytest (>=7.0.0)"] [[package]] name = "eth-rlp" -version = "0.2.1" +version = "1.0.1" description = "eth-rlp: RLP definitions for common Ethereum objects in Python" -category = "main" optional = false -python-versions = ">=3.6, <4" +python-versions = ">=3.8, <4" +files = [ + {file = "eth-rlp-1.0.1.tar.gz", hash = "sha256:d61dbda892ee1220f28fb3663c08f6383c305db9f1f5624dc585c9cd05115027"}, + {file = "eth_rlp-1.0.1-py3-none-any.whl", hash = "sha256:dd76515d71654277377d48876b88e839d61553aaf56952e580bb7cebef2b1517"}, +] [package.dependencies] -eth-utils = ">=1.0.1,<2" +eth-utils = ">=2.0.0" hexbytes = ">=0.1.0,<1" -rlp = ">=0.6.0,<3" +rlp = ">=0.6.0" +typing-extensions = {version = ">=4.0.1", markers = "python_version <= \"3.11\""} [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "bumpversion (>=0.5.3,<1)", "eth-hash", "flake8 (==3.7.9)", "ipython", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=3.0.0,<4)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "pytest (==5.4.1)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)", "tox (==3.14.6)", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=3.0.0,<4)"] -test = ["eth-hash", "pytest-xdist", "pytest (==5.4.1)", "tox (==3.14.6)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash[pycryptodome]", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +test = ["eth-hash[pycryptodome]", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-typing" -version = "2.3.0" +version = "3.5.2" description = "eth-typing: Common type annotations for ethereum python packages" -category = "main" optional = false -python-versions = ">=3.5, <4" +python-versions = ">=3.7.2, <4" +files = [ + {file = "eth-typing-3.5.2.tar.gz", hash = "sha256:22bf051ddfaa35ff827c30090de167e5c5b8cc6d343f7f35c9b1c7553f6ab64d"}, + {file = "eth_typing-3.5.2-py3-none-any.whl", hash = "sha256:1842e628fb1ffa929b94f89a9d33caafbeb9978dc96abb6036a12bc91f1c624b"}, +] + +[package.dependencies] +typing-extensions = ">=4.0.1" [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "pytest (>=4.4,<4.5)", "pytest-xdist", "tox (>=2.9.1,<3)", "flake8 (==3.8.3)", "isort (>=4.2.15,<5)", "mypy (==0.782)", "pydocstyle (>=3.0.0,<4)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)"] -lint = ["flake8 (==3.8.3)", "isort (>=4.2.15,<5)", "mypy (==0.782)", "pydocstyle (>=3.0.0,<4)"] -test = ["pytest (>=4.4,<4.5)", "pytest-xdist", "tox (>=2.9.1,<3)"] +dev = ["black (>=23)", "build (>=0.9.0)", "bumpversion (>=0.5.3)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "ipython", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=6.0.0)", "pytest (>=7.0.0)", "pytest-watch (>=4.1.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "types-setuptools", "wheel"] +docs = ["sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +lint = ["black (>=23)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=6.0.0)", "types-setuptools"] +test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-utils" -version = "1.10.0" +version = "2.3.1" description = "eth-utils: Common utility functions for python code that interacts with Ethereum" -category = "main" optional = false -python-versions = ">=3.5,!=3.5.2,<4" +python-versions = ">=3.7,<4" +files = [ + {file = "eth-utils-2.3.1.tar.gz", hash = "sha256:56a969b0536d4969dcb27e580521de35abf2dbed8b1bf072b5c80770c4324e27"}, + {file = "eth_utils-2.3.1-py3-none-any.whl", hash = "sha256:614eedc5ffcaf4e6708ca39e23b12bd69526a312068c1170c773bd1307d13972"}, +] [package.dependencies] -cytoolz = {version = ">=0.10.1,<1.0.0", markers = "implementation_name == \"cpython\""} -eth-hash = ">=0.3.1,<0.4.0" -eth-typing = ">=2.2.1,<3.0.0" -toolz = {version = ">0.8.2,<1", markers = "implementation_name == \"pypy\""} +cytoolz = {version = ">=0.10.1", markers = "implementation_name == \"cpython\""} +eth-hash = ">=0.3.1" +eth-typing = ">=3.0.0" +toolz = {version = ">0.8.2", markers = "implementation_name == \"pypy\""} [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel (>=0.30.0,<1.0.0)", "twine (>=1.13,<2)", "ipython", "hypothesis (>=4.43.0,<5.0.0)", "pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)", "black (>=18.6b4,<19)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.720)", "pydocstyle (>=5.0.0,<6)", "pytest (>=3.4.1,<4.0.0)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<2)", "towncrier (>=19.2.0,<20)"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<2)", "towncrier (>=19.2.0,<20)"] -lint = ["black (>=18.6b4,<19)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.720)", "pydocstyle (>=5.0.0,<6)", "pytest (>=3.4.1,<4.0.0)"] -test = ["hypothesis (>=4.43.0,<5.0.0)", "pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)"] +dev = ["black (>=23)", "build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash[pycryptodome]", "flake8 (==3.8.3)", "hypothesis (>=4.43.0)", "ipython", "isort (>=5.11.0)", "mypy (==0.971)", "pydocstyle (>=5.0.0)", "pytest (>=7.0.0)", "pytest-watch (>=4.1.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "types-setuptools", "wheel"] +docs = ["sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +lint = ["black (>=23)", "flake8 (==3.8.3)", "isort (>=5.11.0)", "mypy (==0.971)", "pydocstyle (>=5.0.0)", "types-setuptools"] +test = ["hypothesis (>=4.43.0)", "mypy (==0.971)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "types-setuptools"] [[package]] name = "execnet" -version = "1.9.0" +version = "2.0.2" description = "execnet: rapid multi-Python deployment" -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" +files = [ + {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, + {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, +] [package.extras] -testing = ["pre-commit"] +testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "frozenlist" -version = "1.3.0" +version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, +] [[package]] name = "hexbytes" -version = "0.2.2" +version = "0.3.1" description = "hexbytes: Python `bytes` subclass that decodes hex, with a readable console output" -category = "main" optional = false -python-versions = ">=3.6, <4" +python-versions = ">=3.7, <4" +files = [ + {file = "hexbytes-0.3.1-py3-none-any.whl", hash = "sha256:383595ad75026cf00abd570f44b368c6cdac0c6becfae5c39ff88829877f8a59"}, + {file = "hexbytes-0.3.1.tar.gz", hash = "sha256:a3fe35c6831ee8fafd048c4c086b986075fc14fd46258fa24ecb8d65745f9a9d"}, +] [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "bumpversion (>=0.5.3,<1)", "eth-utils (>=1.0.1,<2)", "flake8 (==3.7.9)", "hypothesis (>=3.44.24,<4)", "ipython", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "pytest (==5.4.1)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)", "tox (==3.14.6)", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)"] -test = ["eth-utils (>=1.0.1,<2)", "hypothesis (>=3.44.24,<4)", "pytest-xdist", "pytest (==5.4.1)", "tox (==3.14.6)"] +dev = ["black (>=22)", "bumpversion (>=0.5.3)", "eth-utils (>=1.0.1,<3)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "hypothesis (>=3.44.24,<=6.31.6)", "ipython", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=5.0.0)", "pytest (>=7.0.0)", "pytest-watch (>=4.1.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +doc = ["sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +lint = ["black (>=22)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=5.0.0)"] +test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "hypothesis" version = "6.27.3" description = "A library for property-based testing" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "hypothesis-6.27.3-py3-none-any.whl", hash = "sha256:1c4568f40ca893c884330a1de0e0e5dcb1e867c60a56f414cb7bce97afc8dfec"}, + {file = "hypothesis-6.27.3.tar.gz", hash = "sha256:587da483bcc324494cec09cbbde3396c00da280c1732e387d7b5b89eff1aaff3"}, +] [package.dependencies] attrs = ">=19.2.0" sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] -all = ["black (>=19.10b0)", "click (>=7.0)", "django (>=2.2)", "dpcontracts (>=0.4)", "lark-parser (>=0.6.5)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=0.25)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "importlib-resources (>=3.3.0)", "importlib-metadata (>=3.6)", "backports.zoneinfo (>=0.2.1)", "tzdata (>=2020.4)"] -cli = ["click (>=7.0)", "black (>=19.10b0)", "rich (>=9.0.0)"] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "django (>=2.2)", "dpcontracts (>=0.4)", "importlib-metadata (>=3.6)", "importlib-resources (>=3.3.0)", "lark-parser (>=0.6.5)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=0.25)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2020.4)"] +cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] codemods = ["libcst (>=0.3.16)"] dateutil = ["python-dateutil (>=1.4)"] -django = ["pytz (>=2014.1)", "django (>=2.2)"] +django = ["django (>=2.2)", "pytz (>=2014.1)"] dpcontracts = ["dpcontracts (>=0.4)"] ghostwriter = ["black (>=19.10b0)"] lark = ["lark-parser (>=0.6.5)"] @@ -511,236 +1140,510 @@ pandas = ["pandas (>=0.25)"] pytest = ["pytest (>=4.6)"] pytz = ["pytz (>=2014.1)"] redis = ["redis (>=3.0.0)"] -zoneinfo = ["importlib-resources (>=3.3.0)", "backports.zoneinfo (>=0.2.1)", "tzdata (>=2020.4)"] +zoneinfo = ["backports.zoneinfo (>=0.2.1)", "importlib-resources (>=3.3.0)", "tzdata (>=2020.4)"] [[package]] name = "idna" -version = "3.3" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] [[package]] -name = "inflection" -version = "0.5.0" -description = "A port of Ruby on Rails inflector to Python" -category = "main" +name = "importlib-metadata" +version = "7.0.1" +description = "Read metadata from Python packages" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, + {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" -category = "main" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" optional = false -python-versions = "*" +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] [[package]] -name = "ipfshttpclient" -version = "0.8.0a2" -description = "Python IPFS HTTP CLIENT library" -category = "main" +name = "jsonschema" +version = "4.21.1" +description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.6.2,!=3.7.0,!=3.7.1" +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.21.1-py3-none-any.whl", hash = "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f"}, + {file = "jsonschema-4.21.1.tar.gz", hash = "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"}, +] [package.dependencies] -multiaddr = ">=0.0.7" -requests = ">=2.11" +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -category = "main" +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" optional = false -python-versions = "*" +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] [package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] +referencing = ">=0.31.0" [[package]] name = "lazy-object-proxy" -version = "1.7.1" +version = "1.10.0" description = "A fast and thorough lazy object proxy." -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, + {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, +] [[package]] name = "lru-dict" -version = "1.1.7" +version = "1.2.0" description = "An Dict like LRU container." -category = "main" optional = false python-versions = "*" +files = [ + {file = "lru-dict-1.2.0.tar.gz", hash = "sha256:13c56782f19d68ddf4d8db0170041192859616514c706b126d0df2ec72a11bd7"}, + {file = "lru_dict-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:de906e5486b5c053d15b7731583c25e3c9147c288ac8152a6d1f9bccdec72641"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604d07c7604b20b3130405d137cae61579578b0e8377daae4125098feebcb970"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:203b3e78d03d88f491fa134f85a42919020686b6e6f2d09759b2f5517260c651"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:020b93870f8c7195774cbd94f033b96c14f51c57537969965c3af300331724fe"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1184d91cfebd5d1e659d47f17a60185bbf621635ca56dcdc46c6a1745d25df5c"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc42882b554a86e564e0b662da47b8a4b32fa966920bd165e27bb8079a323bc1"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:18ee88ada65bd2ffd483023be0fa1c0a6a051ef666d1cd89e921dcce134149f2"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:756230c22257597b7557eaef7f90484c489e9ba78e5bb6ab5a5bcfb6b03cb075"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c4da599af36618881748b5db457d937955bb2b4800db891647d46767d636c408"}, + {file = "lru_dict-1.2.0-cp310-cp310-win32.whl", hash = "sha256:35a142a7d1a4fd5d5799cc4f8ab2fff50a598d8cee1d1c611f50722b3e27874f"}, + {file = "lru_dict-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:6da5b8099766c4da3bf1ed6e7d7f5eff1681aff6b5987d1258a13bd2ed54f0c9"}, + {file = "lru_dict-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b20b7c9beb481e92e07368ebfaa363ed7ef61e65ffe6e0edbdbaceb33e134124"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22147367b296be31cc858bf167c448af02435cac44806b228c9be8117f1bfce4"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a3091abeb95e707f381a8b5b7dc8e4ee016316c659c49b726857b0d6d1bd7a"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:877801a20f05c467126b55338a4e9fa30e2a141eb7b0b740794571b7d619ee11"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d3336e901acec897bcd318c42c2b93d5f1d038e67688f497045fc6bad2c0be7"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8dafc481d2defb381f19b22cc51837e8a42631e98e34b9e0892245cc96593deb"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:87bbad3f5c3de8897b8c1263a9af73bbb6469fb90e7b57225dad89b8ef62cd8d"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:25f9e0bc2fe8f41c2711ccefd2871f8a5f50a39e6293b68c3dec576112937aad"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ae301c282a499dc1968dd633cfef8771dd84228ae9d40002a3ea990e4ff0c469"}, + {file = "lru_dict-1.2.0-cp311-cp311-win32.whl", hash = "sha256:c9617583173a29048e11397f165501edc5ae223504a404b2532a212a71ecc9ed"}, + {file = "lru_dict-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6b7a031e47421d4b7aa626b8c91c180a9f037f89e5d0a71c4bb7afcf4036c774"}, + {file = "lru_dict-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ea2ac3f7a7a2f32f194c84d82a034e66780057fd908b421becd2f173504d040e"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd46c94966f631a81ffe33eee928db58e9fbee15baba5923d284aeadc0e0fa76"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:086ce993414f0b28530ded7e004c77dc57c5748fa6da488602aa6e7f79e6210e"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df25a426446197488a6702954dcc1de511deee20c9db730499a2aa83fddf0df1"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c53b12b89bd7a6c79f0536ff0d0a84fdf4ab5f6252d94b24b9b753bd9ada2ddf"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f9484016e6765bd295708cccc9def49f708ce07ac003808f69efa386633affb9"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d0f7ec902a0097ac39f1922c89be9eaccf00eb87751e28915320b4f72912d057"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:981ef3edc82da38d39eb60eae225b88a538d47b90cce2e5808846fd2cf64384b"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e25b2e90a032dc248213af7f3f3e975e1934b204f3b16aeeaeaff27a3b65e128"}, + {file = "lru_dict-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:59f3df78e94e07959f17764e7fa7ca6b54e9296953d2626a112eab08e1beb2db"}, + {file = "lru_dict-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:de24b47159e07833aeab517d9cb1c3c5c2d6445cc378b1c2f1d8d15fb4841d63"}, + {file = "lru_dict-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d0dd4cd58220351233002f910e35cc01d30337696b55c6578f71318b137770f9"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a87bdc291718bbdf9ea4be12ae7af26cbf0706fa62c2ac332748e3116c5510a7"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05fb8744f91f58479cbe07ed80ada6696ec7df21ea1740891d4107a8dd99a970"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00f6e8a3fc91481b40395316a14c94daa0f0a5de62e7e01a7d589f8d29224052"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b172fce0a0ffc0fa6d282c14256d5a68b5db1e64719c2915e69084c4b6bf555"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e707d93bae8f0a14e6df1ae8b0f076532b35f00e691995f33132d806a88e5c18"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b9ec7a4a0d6b8297102aa56758434fb1fca276a82ed7362e37817407185c3abb"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f404dcc8172da1f28da9b1f0087009578e608a4899b96d244925c4f463201f2a"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1171ad3bff32aa8086778be4a3bdff595cc2692e78685bcce9cb06b96b22dcc2"}, + {file = "lru_dict-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:0c316dfa3897fabaa1fe08aae89352a3b109e5f88b25529bc01e98ac029bf878"}, + {file = "lru_dict-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5919dd04446bc1ee8d6ecda2187deeebfff5903538ae71083e069bc678599446"}, + {file = "lru_dict-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fbf36c5a220a85187cacc1fcb7dd87070e04b5fc28df7a43f6842f7c8224a388"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:712e71b64da181e1c0a2eaa76cd860265980cd15cb0e0498602b8aa35d5db9f8"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f54908bf91280a9b8fa6a8c8f3c2f65850ce6acae2852bbe292391628ebca42f"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3838e33710935da2ade1dd404a8b936d571e29268a70ff4ca5ba758abb3850df"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5d5a5f976b39af73324f2b793862859902ccb9542621856d51a5993064f25e4"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8bda3a9afd241ee0181661decaae25e5336ce513ac268ab57da737eacaa7871f"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd2cd1b998ea4c8c1dad829fc4fa88aeed4dee555b5e03c132fc618e6123f168"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b55753ee23028ba8644fd22e50de7b8f85fa60b562a0fafaad788701d6131ff8"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7e51fa6a203fa91d415f3b2900e5748ec8e06ad75777c98cc3aeb3983ca416d7"}, + {file = "lru_dict-1.2.0-cp38-cp38-win32.whl", hash = "sha256:cd6806313606559e6c7adfa0dbeb30fc5ab625f00958c3d93f84831e7a32b71e"}, + {file = "lru_dict-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d90a70c53b0566084447c3ef9374cc5a9be886e867b36f89495f211baabd322"}, + {file = "lru_dict-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3ea7571b6bf2090a85ff037e6593bbafe1a8598d5c3b4560eb56187bcccb4dc"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:287c2115a59c1c9ed0d5d8ae7671e594b1206c36ea9df2fca6b17b86c468ff99"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5ccfd2291c93746a286c87c3f895165b697399969d24c54804ec3ec559d4e43"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b710f0f4d7ec4f9fa89dfde7002f80bcd77de8024017e70706b0911ea086e2ef"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5345bf50e127bd2767e9fd42393635bbc0146eac01f6baf6ef12c332d1a6a329"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:291d13f85224551913a78fe695cde04cbca9dcb1d84c540167c443eb913603c9"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d5bb41bc74b321789803d45b124fc2145c1b3353b4ad43296d9d1d242574969b"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0facf49b053bf4926d92d8d5a46fe07eecd2af0441add0182c7432d53d6da667"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:987b73a06bcf5a95d7dc296241c6b1f9bc6cda42586948c9dabf386dc2bef1cd"}, + {file = "lru_dict-1.2.0-cp39-cp39-win32.whl", hash = "sha256:231d7608f029dda42f9610e5723614a35b1fff035a8060cf7d2be19f1711ace8"}, + {file = "lru_dict-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:71da89e134747e20ed5b8ad5b4ee93fc5b31022c2b71e8176e73c5a44699061b"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:21b3090928c7b6cec509e755cc3ab742154b33660a9b433923bd12c37c448e3e"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaecd7085212d0aa4cd855f38b9d61803d6509731138bf798a9594745953245b"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ead83ac59a29d6439ddff46e205ce32f8b7f71a6bd8062347f77e232825e3d0a"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:312b6b2a30188586fe71358f0f33e4bac882d33f5e5019b26f084363f42f986f"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b30122e098c80e36d0117810d46459a46313421ce3298709170b687dc1240b02"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f010cfad3ab10676e44dc72a813c968cd586f37b466d27cde73d1f7f1ba158c2"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20f5f411f7751ad9a2c02e80287cedf69ae032edd321fe696e310d32dd30a1f8"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:afdadd73304c9befaed02eb42f5f09fdc16288de0a08b32b8080f0f0f6350aa6"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7ab0c10c4fa99dc9e26b04e6b62ac32d2bcaea3aad9b81ec8ce9a7aa32b7b1b"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:edad398d5d402c43d2adada390dd83c74e46e020945ff4df801166047013617e"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:91d577a11b84387013815b1ad0bb6e604558d646003b44c92b3ddf886ad0f879"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb12f19cdf9c4f2d9aa259562e19b188ff34afab28dd9509ff32a3f1c2c29326"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e4c85aa8844bdca3c8abac3b7f78da1531c74e9f8b3e4890c6e6d86a5a3f6c0"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c6acbd097b15bead4de8e83e8a1030bb4d8257723669097eac643a301a952f0"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b6613daa851745dd22b860651de930275be9d3e9373283a2164992abacb75b62"}, +] -[[package]] -name = "multiaddr" -version = "0.0.9" -description = "Python implementation of jbenet's multiaddr" -category = "main" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" - -[package.dependencies] -base58 = "*" -netaddr = "*" -six = "*" -varint = "*" +[package.extras] +test = ["pytest"] [[package]] name = "multidict" -version = "6.0.2" +version = "6.0.5" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"}, + {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"}, + {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"}, + {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"}, + {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"}, + {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"}, + {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"}, + {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"}, + {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"}, + {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"}, + {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"}, + {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"}, + {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"}, + {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"}, + {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"}, + {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, +] [[package]] name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "mythx-models" -version = "1.9.1" -description = "Python domain model classes for the MythX platform" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -inflection = "0.5.0" -jsonschema = "<4.0.0" -python-dateutil = "2.8.1" - -[[package]] -name = "netaddr" -version = "0.8.0" -description = "A network address manipulation library for Python" -category = "main" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = "*" +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] [[package]] name = "packaging" -version = "21.3" +version = "23.2" description = "Core utilities for Python packages" -category = "main" optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] [[package]] name = "parsimonious" -version = "0.8.1" +version = "0.9.0" description = "(Soon to be) the fastest pure-Python PEG parser I could muster" -category = "main" optional = false python-versions = "*" +files = [ + {file = "parsimonious-0.9.0.tar.gz", hash = "sha256:b2ad1ae63a2f65bd78f5e0a8ac510a98f3607a43f1db2a8d46636a5d9e4a30c1"}, +] [package.dependencies] -six = ">=1.9.0" +regex = ">=2022.3.15" [[package]] name = "pathspec" -version = "0.9.0" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] [[package]] name = "platformdirs" -version = "2.4.1" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" +version = "4.2.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, +] [package.extras] -docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] -test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" -version = "1.0.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, +] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "prettytable" +version = "3.10.0" +description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "prettytable-3.10.0-py3-none-any.whl", hash = "sha256:6536efaf0757fdaa7d22e78b3aac3b69ea1b7200538c2c6995d649365bddab92"}, + {file = "prettytable-3.10.0.tar.gz", hash = "sha256:9665594d137fb08a1117518c25551e0ede1687197cf353a4fdc78d27e1073568"}, +] + +[package.dependencies] +wcwidth = "*" + +[package.extras] +tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"] + [[package]] name = "prompt-toolkit" -version = "3.0.26" +version = "3.0.43" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, +] [package.dependencies] wcwidth = "*" [[package]] name = "protobuf" -version = "3.19.4" -description = "Protocol Buffers" -category = "main" +version = "4.25.3" +description = "" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" +files = [ + {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, + {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, + {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, + {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, + {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, + {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, + {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, + {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, + {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, +] [[package]] name = "psutil" -version = "5.9.0" +version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." -category = "main" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, + {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, + {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, + {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, + {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, + {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, + {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, + {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, + {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, + {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, +] [package.extras] -test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] [[package]] name = "py" version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] [[package]] name = "py-solc-ast" -version = "1.2.9" +version = "1.2.10" description = "A tool for exploring the abstract syntax tree generated by solc." -category = "main" optional = false python-versions = ">=3.6, <4" +files = [ + {file = "py-solc-ast-1.2.10.tar.gz", hash = "sha256:fb5defdb6e82ca4175a0ecd1c04ce37134df0c141fc60b08a5068e119d7e9850"}, + {file = "py_solc_ast-1.2.10-py3-none-any.whl", hash = "sha256:afef589268bea5ce10e217cf147c0a5e539a83ee48efba91d9b0d6f611cd05cd"}, +] [[package]] name = "py-solc-x" version = "1.1.1" description = "Python wrapper and version management tool for the solc Solidity compiler." -category = "main" optional = false python-versions = ">=3.6, <4" +files = [ + {file = "py-solc-x-1.1.1.tar.gz", hash = "sha256:d8b0bd2b04f47cff6e92181739d9e94e41b2d62f056900761c797fa5babc76b6"}, + {file = "py_solc_x-1.1.1-py3-none-any.whl", hash = "sha256:8f5caa4f54e227fc301e2e4c8aa868e869c2bc0c6636aa9e8115f8414bb891f9"}, +] [package.dependencies] requests = ">=2.19.0,<3" @@ -748,70 +1651,83 @@ semantic-version = ">=2.8.1,<3" [[package]] name = "pycryptodome" -version = "3.14.1" +version = "3.20.0" description = "Cryptographic library for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodome-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818"}, + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044"}, + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win32.whl", hash = "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e"}, + {file = "pycryptodome-3.20.0.tar.gz", hash = "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7"}, +] [[package]] name = "pygments" -version = "2.11.2" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" +files = [ + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, +] + +[package.extras] +plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pygments-lexer-solidity" version = "0.7.0" description = "Solidity lexer for Pygments (includes Yul intermediate language)" -category = "main" optional = false python-versions = ">=3.3, <4" +files = [ + {file = "pygments-lexer-solidity-0.7.0.tar.gz", hash = "sha256:a347fd96981838331b6d98b0f891776908a49406d343ff2a40a6a1c8475a9350"}, +] [package.dependencies] pygments = ">=2.1" -[[package]] -name = "pyjwt" -version = "1.7.1" -description = "JSON Web Token implementation in Python" -category = "main" -optional = false -python-versions = "*" - -[package.extras] -crypto = ["cryptography (>=1.4)"] -flake8 = ["flake8", "flake8-import-order", "pep8-naming"] -test = ["pytest (>=4.0.1,<5.0.0)", "pytest-cov (>=2.6.0,<3.0.0)", "pytest-runner (>=4.2,<5.0.0)"] - -[[package]] -name = "pyparsing" -version = "3.0.7" -description = "Python parsing module" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pyrsistent" -version = "0.18.1" -description = "Persistent/Functional/Immutable data structures" -category = "main" -optional = false -python-versions = ">=3.7" - [[package]] name = "pytest" version = "6.2.5" description = "pytest: simple powerful testing with Python" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, +] [package.dependencies] atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} @@ -828,11 +1744,14 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm [[package]] name = "pytest-forked" -version = "1.4.0" +version = "1.6.0" description = "run tests in isolated forked subprocesses" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "pytest-forked-1.6.0.tar.gz", hash = "sha256:4dafd46a9a600f65d822b8f605133ecf5b3e1941ebb3588e943b4e3eb71a5a3f"}, + {file = "pytest_forked-1.6.0-py3-none-any.whl", hash = "sha256:810958f66a91afb1a1e2ae83089d8dc1cd2437ac96b12963042fbb9fb4d16af0"}, +] [package.dependencies] py = "*" @@ -842,9 +1761,12 @@ pytest = ">=3.10" name = "pytest-xdist" version = "1.34.0" description = "pytest xdist plugin for distributed testing and loop-on-failing modes" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pytest-xdist-1.34.0.tar.gz", hash = "sha256:340e8e83e2a4c0d861bdd8d05c5d7b7143f6eea0aba902997db15c2a86be04ee"}, + {file = "pytest_xdist-1.34.0-py2.py3-none-any.whl", hash = "sha256:ba5d10729372d65df3ac150872f9df5d2ed004a3b0d499cc0164aafedd8c7b66"}, +] [package.dependencies] execnet = ">=1.1" @@ -857,11 +1779,14 @@ testing = ["filelock"] [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] [package.dependencies] six = ">=1.5" @@ -870,193 +1795,545 @@ six = ">=1.5" name = "python-dotenv" version = "0.16.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = "*" +files = [ + {file = "python-dotenv-0.16.0.tar.gz", hash = "sha256:9fa413c37d4652d3fa02fea0ff465c384f5db75eab259c4fc5d0c5b8bf20edd4"}, + {file = "python_dotenv-0.16.0-py2.py3-none-any.whl", hash = "sha256:31d752f5b748f4e292448c9a0cac6a08ed5e6f4cefab85044462dcad56905cec"}, +] [package.extras] cli = ["click (>=5.0)"] [[package]] -name = "pythx" -version = "1.6.1" -description = "A Python library for the MythX platform" -category = "main" +name = "pyunormalize" +version = "15.1.0" +description = "Unicode normalization forms (NFC, NFKC, NFD, NFKD). A library independent from the Python core Unicode database." optional = false -python-versions = "*" - -[package.dependencies] -inflection = "0.5.0" -mythx-models = "1.9.1" -PyJWT = ">=1.7.0,<1.8.0" -python-dateutil = ">=2.8.0,<2.9.0" -requests = ">=2.0.0,<3.0.0" +python-versions = ">=3.6" +files = [ + {file = "pyunormalize-15.1.0.tar.gz", hash = "sha256:cf4a87451a0f1cb76911aa97f432f4579e1f564a2f0c84ce488c73a73901b6c1"}, +] [[package]] name = "pywin32" -version = "303" +version = "306" description = "Python for Window Extensions" -category = "main" optional = false python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] [[package]] name = "pyyaml" -version = "5.4.1" +version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "referencing" +version = "0.33.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.33.0-py3-none-any.whl", hash = "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5"}, + {file = "referencing-0.33.0.tar.gz", hash = "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "regex" +version = "2023.12.25" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, +] [[package]] name = "requests" -version = "2.27.1" +version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} -urllib3 = ">=1.21.1,<1.27" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" [package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rlp" -version = "2.0.1" -description = "A package for Recursive Length Prefix encoding and decoding" -category = "main" +version = "4.0.0" +description = "rlp: A package for Recursive Length Prefix encoding and decoding" optional = false -python-versions = "*" +python-versions = ">=3.8, <4" +files = [ + {file = "rlp-4.0.0-py3-none-any.whl", hash = "sha256:1747fd933e054e6d25abfe591be92e19a4193a56c93981c05bd0f84dfe279f14"}, + {file = "rlp-4.0.0.tar.gz", hash = "sha256:61a5541f86e4684ab145cb849a5929d2ced8222930a570b3941cf4af16b72a78"}, +] [package.dependencies] -eth-utils = ">=1.0.2,<2" +eth-utils = ">=2" [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "bumpversion (>=0.5.3,<1)", "flake8 (==3.4.1)", "hypothesis (==5.19.0)", "ipython", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "pytest (==5.4.3)", "setuptools (>=36.2.0)", "sphinx-rtd-theme (>=0.1.9)", "tox (>=2.9.1,<3)", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)"] -lint = ["flake8 (==3.4.1)"] -rust-backend = ["rusty-rlp (>=0.1.15,<0.2)"] -test = ["hypothesis (==5.19.0)", "pytest (==5.4.3)", "tox (>=2.9.1,<3)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "hypothesis (==5.19.0)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +rust-backend = ["rusty-rlp (>=0.2.1,<0.3)"] +test = ["hypothesis (==5.19.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] + +[[package]] +name = "rpds-py" +version = "0.18.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.18.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e"}, + {file = "rpds_py-0.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88"}, + {file = "rpds_py-0.18.0-cp310-none-win32.whl", hash = "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337"}, + {file = "rpds_py-0.18.0-cp310-none-win_amd64.whl", hash = "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836"}, + {file = "rpds_py-0.18.0-cp311-none-win32.whl", hash = "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1"}, + {file = "rpds_py-0.18.0-cp311-none-win_amd64.whl", hash = "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7"}, + {file = "rpds_py-0.18.0-cp312-none-win32.whl", hash = "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98"}, + {file = "rpds_py-0.18.0-cp312-none-win_amd64.whl", hash = "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594"}, + {file = "rpds_py-0.18.0-cp38-none-win32.whl", hash = "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e"}, + {file = "rpds_py-0.18.0-cp38-none-win_amd64.whl", hash = "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20"}, + {file = "rpds_py-0.18.0-cp39-none-win32.whl", hash = "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7"}, + {file = "rpds_py-0.18.0-cp39-none-win_amd64.whl", hash = "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f"}, + {file = "rpds_py-0.18.0.tar.gz", hash = "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d"}, +] [[package]] name = "semantic-version" -version = "2.8.5" +version = "2.10.0" description = "A library implementing the 'SemVer' scheme." -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "setuptools" -version = "62.0.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" -optional = false -python-versions = ">=3.7" +python-versions = ">=2.7" +files = [ + {file = "semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177"}, + {file = "semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c"}, +] [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-enabler (>=1.0.1)", "pytest-perf", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "wheel", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "jaraco.path (>=3.2.0)", "build", "filelock (>=3.4.0)", "pip-run (>=8.8)", "ini2toml[lite] (>=0.9)", "tomli-w (>=1.0.0)", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy (>=0.9.1)"] -testing-integration = ["pytest", "pytest-xdist", "pytest-enabler", "virtualenv (>=13.0.0)", "tomli", "wheel", "jaraco.path (>=3.2.0)", "jaraco.envs (>=2.2)", "build", "filelock (>=3.4.0)"] +dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1)", "coverage", "flake8", "nose2", "readme-renderer (<25.0)", "tox", "wheel", "zest.releaser[recommended]"] +doc = ["Sphinx", "sphinx-rtd-theme"] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "slither-analyzer" +version = "0.10.2" +description = "Slither is a Solidity and Vyper static analysis framework written in Python 3." +optional = false +python-versions = ">=3.8" +files = [ + {file = "slither-analyzer-0.10.2.tar.gz", hash = "sha256:d09c22988d620fc7678a735537729c8f3a33f6a6041c5adff2cbfd8e8d553b0d"}, + {file = "slither_analyzer-0.10.2-py3-none-any.whl", hash = "sha256:8c24216314d4a1482d7090e6b0b1fd9fa9095be066967dbc7dbbd557ebe70654"}, +] + +[package.dependencies] +crytic-compile = ">=0.3.7,<0.4.0" +eth-abi = ">=4.0.0" +eth-typing = ">=3.0.0" +eth-utils = ">=2.1.0" +packaging = "*" +prettytable = ">=3.3.0" +pycryptodome = ">=3.4.6" +web3 = ">=6.0.0" + +[package.extras] +dev = ["openai", "slither-analyzer[doc,lint,test]"] +doc = ["pdoc"] +lint = ["black (==22.3.0)", "pylint (==3.0.3)"] +test = ["coverage[toml]", "deepdiff", "filelock", "numpy", "pytest", "pytest-cov", "pytest-insta", "pytest-xdist"] + +[[package]] +name = "solc-select" +version = "1.0.4" +description = "Manage multiple Solidity compiler versions." +optional = false +python-versions = ">=3.6" +files = [ + {file = "solc-select-1.0.4.tar.gz", hash = "sha256:db7b9de009af6de3a5416b80bbe5b6d636bf314703c016319b8c1231e248a6c7"}, + {file = "solc_select-1.0.4-py3-none-any.whl", hash = "sha256:9a28b8a612ff18a171929d23e2ed68a6263f4e11784fc47fa81476a3219874cb"}, +] + +[package.dependencies] +packaging = "*" +pycryptodome = ">=3.4.6" [[package]] name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "main" optional = false python-versions = "*" +files = [ + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, +] [[package]] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] [[package]] name = "tomli" -version = "2.0.0" +version = "2.0.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] [[package]] name = "toolz" -version = "0.11.2" +version = "0.12.1" description = "List processing tools and functional utilities" -category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" +files = [ + {file = "toolz-0.12.1-py3-none-any.whl", hash = "sha256:d22731364c07d72eea0a0ad45bafb2c2937ab6fd38a3507bf55eae8744aa7d85"}, + {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, +] [[package]] name = "tqdm" -version = "4.62.3" +version = "4.66.2" description = "Fast, Extensible Progress Meter" -category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, + {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["py-make (>=0.1.0)", "twine", "wheel"] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] telegram = ["requests"] [[package]] name = "typing-extensions" -version = "4.0.1" -description = "Backported and Experimental Type Hints for Python 3.6+" -category = "main" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, +] [[package]] name = "urllib3" -version = "1.26.8" +version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] [package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "varint" -version = "1.0.2" -description = "Simple python varint implementation" -category = "main" -optional = false -python-versions = "*" +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "vvm" version = "0.1.0" description = "Vyper version management tool" -category = "main" optional = false python-versions = ">=3.6, <4" +files = [ + {file = "vvm-0.1.0-py3-none-any.whl", hash = "sha256:814c67bc8049d45ea8049bc26b04ce4065015f5a3e2896a1a2a2a44ab6e85edc"}, + {file = "vvm-0.1.0.tar.gz", hash = "sha256:a1474915b12e0084299d2c7fe7d72434fa99c00ebb117e400756a5d7e0edac2a"}, +] [package.dependencies] requests = ">=2.19.0,<3" @@ -1064,962 +2341,368 @@ semantic-version = ">=2.8.1,<3" [[package]] name = "vyper" -version = "0.3.1" +version = "0.3.10" description = "Vyper: the Pythonic Programming Language for the EVM" -category = "main" optional = false -python-versions = ">=3.7,<3.10" +python-versions = ">=3.10,<4" +files = [ + {file = "vyper-0.3.10-py3-none-any.whl", hash = "sha256:05636302341bf89602b19f749fcabc8d184a265d8eea4a45c20b3259780353b0"}, + {file = "vyper-0.3.10.tar.gz", hash = "sha256:8dc1f501caab417fb0ce9c68a6944587f0147ec7cc7d3889cf3a45c19466e489"}, +] [package.dependencies] -asttokens = "2.0.5" +asttokens = ">=2.0.5,<3" +cbor2 = ">=5.4.6,<6" +importlib-metadata = "*" +packaging = ">=23.1,<24" pycryptodome = ">=3.5.1,<4" -semantic-version = "2.8.5" +wheel = "*" [package.extras] -dev = ["pytest (>=5.4,<6.0)", "pytest-cov (>=2.10,<3.0)", "pytest-instafail (>=0.4,<1.0)", "pytest-xdist (>=1.32,<2.0)", "eth-tester[py-evm] (>=0.5.0b1,<0.6)", "py-evm (==0.4.0a4)", "web3 (==5.21.0)", "tox (>=3.15,<4.0)", "lark-parser (==0.10.0)", "hypothesis[lark] (>=5.37.1,<6.0)", "black (==21.9b0)", "flake8 (==3.9.2)", "flake8-bugbear (==20.1.4)", "flake8-use-fstring (==1.1)", "isort (==5.9.3)", "mypy (==0.910)", "recommonmark", "sphinx (>=3.0,<4.0)", "sphinx-rtd-theme (>=0.5,<0.6)", "ipython", "pre-commit", "pyinstaller", "twine"] -docs = ["recommonmark", "sphinx (>=3.0,<4.0)", "sphinx-rtd-theme (>=0.5,<0.6)"] -lint = ["black (==21.9b0)", "flake8 (==3.9.2)", "flake8-bugbear (==20.1.4)", "flake8-use-fstring (==1.1)", "isort (==5.9.3)", "mypy (==0.910)"] -test = ["pytest (>=5.4,<6.0)", "pytest-cov (>=2.10,<3.0)", "pytest-instafail (>=0.4,<1.0)", "pytest-xdist (>=1.32,<2.0)", "eth-tester[py-evm] (>=0.5.0b1,<0.6)", "py-evm (==0.4.0a4)", "web3 (==5.21.0)", "tox (>=3.15,<4.0)", "lark-parser (==0.10.0)", "hypothesis[lark] (>=5.37.1,<6.0)"] +dev = ["black (==23.3.0)", "eth-stdlib (==0.2.6)", "eth-tester[py-evm] (>=0.9.0b1,<0.10)", "flake8 (==3.9.2)", "flake8-bugbear (==20.1.4)", "flake8-use-fstring (==1.1)", "hypothesis[lark] (>=5.37.1,<6.0)", "ipython", "isort (==5.9.3)", "lark (==1.1.2)", "mypy (==0.982)", "pre-commit", "py-evm (>=0.7.0a1,<0.8)", "pyinstaller", "pytest (>=6.2.5,<7.0)", "pytest-cov (>=2.10,<3.0)", "pytest-instafail (>=0.4,<1.0)", "pytest-rerunfailures (>=10.2,<11)", "pytest-split (>=0.7.0,<1.0)", "pytest-xdist (>=2.5,<3.0)", "recommonmark", "sphinx (>=6.0,<7.0)", "sphinx-rtd-theme (>=1.2,<1.3)", "tox (>=3.15,<4.0)", "twine", "web3 (==6.0.0)"] +docs = ["recommonmark", "sphinx (>=6.0,<7.0)", "sphinx-rtd-theme (>=1.2,<1.3)"] +lint = ["black (==23.3.0)", "flake8 (==3.9.2)", "flake8-bugbear (==20.1.4)", "flake8-use-fstring (==1.1)", "isort (==5.9.3)", "mypy (==0.982)"] +test = ["eth-stdlib (==0.2.6)", "eth-tester[py-evm] (>=0.9.0b1,<0.10)", "hypothesis[lark] (>=5.37.1,<6.0)", "lark (==1.1.2)", "py-evm (>=0.7.0a1,<0.8)", "pytest (>=6.2.5,<7.0)", "pytest-cov (>=2.10,<3.0)", "pytest-instafail (>=0.4,<1.0)", "pytest-rerunfailures (>=10.2,<11)", "pytest-split (>=0.7.0,<1.0)", "pytest-xdist (>=2.5,<3.0)", "tox (>=3.15,<4.0)", "web3 (==6.0.0)"] [[package]] name = "wcwidth" -version = "0.2.5" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] [[package]] name = "web3" -version = "5.27.0" -description = "Web3.py" -category = "main" +version = "6.15.1" +description = "web3.py" optional = false -python-versions = ">=3.6,<4" +python-versions = ">=3.7.2" +files = [ + {file = "web3-6.15.1-py3-none-any.whl", hash = "sha256:4e4a8313aa4556ecde61c852a62405b853b667498b07da6ff05c29fe8c79096b"}, + {file = "web3-6.15.1.tar.gz", hash = "sha256:f9e7eefc1b3c3d194868a4ef9583b625c18ea3f31a48ebe143183db74898f381"}, +] [package.dependencies] -aiohttp = ">=3.7.4.post0,<4" -eth-abi = ">=2.0.0b6,<3.0.0" -eth-account = ">=0.5.7,<0.6.0" -eth-hash = {version = ">=0.2.0,<1.0.0", extras = ["pycryptodome"]} -eth-typing = ">=2.0.0,<3.0.0" -eth-utils = ">=1.9.5,<2.0.0" -hexbytes = ">=0.1.0,<1.0.0" -ipfshttpclient = "0.8.0a2" -jsonschema = ">=3.2.0,<4.0.0" -lru-dict = ">=1.1.6,<2.0.0" -protobuf = ">=3.10.0,<4" +aiohttp = ">=3.7.4.post0" +eth-abi = ">=4.0.0" +eth-account = ">=0.8.0" +eth-hash = {version = ">=0.5.1", extras = ["pycryptodome"]} +eth-typing = ">=3.0.0" +eth-utils = ">=2.1.0" +hexbytes = ">=0.1.0,<0.4.0" +jsonschema = ">=4.0.0" +lru-dict = ">=1.1.6,<1.3.0" +protobuf = ">=4.21.6" +pyunormalize = ">=15.0.0" pywin32 = {version = ">=223", markers = "platform_system == \"Windows\""} -requests = ">=2.16.0,<3.0.0" -websockets = ">=9.1,<10" +requests = ">=2.16.0" +typing-extensions = ">=4.0.1" +websockets = ">=10.0.0" [package.extras] -dev = ["eth-tester[py-evm] (==v0.6.0-beta.6)", "py-geth (>=3.7.0,<4)", "flake8 (==3.8.3)", "isort (>=4.2.15,<4.3.5)", "mypy (==0.910)", "types-setuptools (>=57.4.4,<58)", "types-requests (>=2.26.1,<3)", "types-protobuf (>=3.18.2,<4)", "mock", "sphinx-better-theme (>=0.1.4)", "click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "py-geth (>=3.6.0,<4)", "py-solc (>=0.4.0)", "pytest (>=4.4.0,<5.0.0)", "sphinx (>=3.0,<4)", "sphinx-rtd-theme (>=0.1.9)", "toposort (>=1.4)", "towncrier (==18.5.0)", "urllib3", "wheel", "bumpversion", "flaky (>=3.7.0,<4)", "hypothesis (>=3.31.2,<6)", "pytest-asyncio (>=0.10.0,<0.11)", "pytest-mock (>=1.10,<2)", "pytest-pythonpath (>=0.3)", "pytest-watch (>=4.2,<5)", "pytest-xdist (>=1.29,<2)", "setuptools (>=38.6.0)", "tox (>=1.8.0)", "tqdm (>4.32,<5)", "twine (>=1.13,<2)", "pluggy (==0.13.1)", "when-changed (>=0.3.0,<0.4)"] -docs = ["mock", "sphinx-better-theme (>=0.1.4)", "click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "py-geth (>=3.6.0,<4)", "py-solc (>=0.4.0)", "pytest (>=4.4.0,<5.0.0)", "sphinx (>=3.0,<4)", "sphinx-rtd-theme (>=0.1.9)", "toposort (>=1.4)", "towncrier (==18.5.0)", "urllib3", "wheel"] -linter = ["flake8 (==3.8.3)", "isort (>=4.2.15,<4.3.5)", "mypy (==0.910)", "types-setuptools (>=57.4.4,<58)", "types-requests (>=2.26.1,<3)", "types-protobuf (>=3.18.2,<4)"] -tester = ["eth-tester[py-evm] (==v0.6.0-beta.6)", "py-geth (>=3.7.0,<4)"] +dev = ["black (>=22.1.0)", "build (>=0.9.0)", "bumpversion", "eth-tester[py-evm] (==v0.9.1-b.2)", "flake8 (==3.8.3)", "flaky (>=3.7.0)", "hypothesis (>=3.31.2)", "importlib-metadata (<5.0)", "ipfshttpclient (==0.8.0a2)", "isort (>=5.11.0)", "mypy (==1.4.1)", "py-geth (>=3.14.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.18.1,<0.23)", "pytest-mock (>=1.10)", "pytest-watch (>=4.2)", "pytest-xdist (>=1.29)", "setuptools (>=38.6.0)", "sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=3.18.0)", "tqdm (>4.32)", "twine (>=1.13)", "types-protobuf (==3.19.13)", "types-requests (>=2.26.1)", "types-setuptools (>=57.4.4)", "when-changed (>=0.3.0)"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +ipfs = ["ipfshttpclient (==0.8.0a2)"] +linter = ["black (>=22.1.0)", "flake8 (==3.8.3)", "isort (>=5.11.0)", "mypy (==1.4.1)", "types-protobuf (==3.19.13)", "types-requests (>=2.26.1)", "types-setuptools (>=57.4.4)"] +tester = ["eth-tester[py-evm] (==v0.9.1-b.2)", "py-geth (>=3.14.0)"] [[package]] name = "websockets" -version = "9.1" +version = "12.0" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -category = "main" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.8" +files = [ + {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, +] + +[[package]] +name = "wheel" +version = "0.42.0" +description = "A built-package format for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "wheel-0.42.0-py3-none-any.whl", hash = "sha256:177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d"}, + {file = "wheel-0.42.0.tar.gz", hash = "sha256:c45be39f7882c9d34243236f2d63cbd58039e360f85d0913425fbd7ceea617a8"}, +] + +[package.extras] +test = ["pytest (>=6.0.0)", "setuptools (>=65)"] [[package]] name = "wrapt" -version = "1.13.3" +version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." -category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] [[package]] name = "yarl" -version = "1.7.2" +version = "1.9.4" description = "Yet another URL library" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, +] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" -[metadata] -lock-version = "1.1" -python-versions = "3.9.10" -content-hash = "7be2872396e18198ccfe02072f89a8496f5ab2848eee7ceea38f2a77cd625bee" - -[metadata.files] -aiohttp = [ - {file = "aiohttp-3.8.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8"}, - {file = "aiohttp-3.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7dadf3c307b31e0e61689cbf9e06be7a867c563d5a63ce9dca578f956609abf8"}, - {file = "aiohttp-3.8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a79004bb58748f31ae1cbe9fa891054baaa46fb106c2dc7af9f8e3304dc30316"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12de6add4038df8f72fac606dff775791a60f113a725c960f2bab01d8b8e6b15"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f0d5f33feb5f69ddd57a4a4bd3d56c719a141080b445cbf18f238973c5c9923"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eaba923151d9deea315be1f3e2b31cc39a6d1d2f682f942905951f4e40200922"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:099ebd2c37ac74cce10a3527d2b49af80243e2a4fa39e7bce41617fbc35fa3c1"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2e5d962cf7e1d426aa0e528a7e198658cdc8aa4fe87f781d039ad75dcd52c516"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fa0ffcace9b3aa34d205d8130f7873fcfefcb6a4dd3dd705b0dab69af6712642"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61bfc23df345d8c9716d03717c2ed5e27374e0fe6f659ea64edcd27b4b044cf7"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:31560d268ff62143e92423ef183680b9829b1b482c011713ae941997921eebc8"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:01d7bdb774a9acc838e6b8f1d114f45303841b89b95984cbb7d80ea41172a9e3"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:97ef77eb6b044134c0b3a96e16abcb05ecce892965a2124c566af0fd60f717e2"}, - {file = "aiohttp-3.8.1-cp310-cp310-win32.whl", hash = "sha256:c2aef4703f1f2ddc6df17519885dbfa3514929149d3ff900b73f45998f2532fa"}, - {file = "aiohttp-3.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:713ac174a629d39b7c6a3aa757b337599798da4c1157114a314e4e391cd28e32"}, - {file = "aiohttp-3.8.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:473d93d4450880fe278696549f2e7aed8cd23708c3c1997981464475f32137db"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b5eeae8e019e7aad8af8bb314fb908dd2e028b3cdaad87ec05095394cce632"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af642b43ce56c24d063325dd2cf20ee012d2b9ba4c3c008755a301aaea720ad"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3630c3ef435c0a7c549ba170a0633a56e92629aeed0e707fec832dee313fb7a"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4a4a4e30bf1edcad13fb0804300557aedd07a92cabc74382fdd0ba6ca2661091"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f8b01295e26c68b3a1b90efb7a89029110d3a4139270b24fda961893216c440"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a25fa703a527158aaf10dafd956f7d42ac6d30ec80e9a70846253dd13e2f067b"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5bfde62d1d2641a1f5173b8c8c2d96ceb4854f54a44c23102e2ccc7e02f003ec"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:51467000f3647d519272392f484126aa716f747859794ac9924a7aafa86cd411"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:03a6d5349c9ee8f79ab3ff3694d6ce1cfc3ced1c9d36200cb8f08ba06bd3b782"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:102e487eeb82afac440581e5d7f8f44560b36cf0bdd11abc51a46c1cd88914d4"}, - {file = "aiohttp-3.8.1-cp36-cp36m-win32.whl", hash = "sha256:4aed991a28ea3ce320dc8ce655875e1e00a11bdd29fe9444dd4f88c30d558602"}, - {file = "aiohttp-3.8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b0e20cddbd676ab8a64c774fefa0ad787cc506afd844de95da56060348021e96"}, - {file = "aiohttp-3.8.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:37951ad2f4a6df6506750a23f7cbabad24c73c65f23f72e95897bb2cecbae676"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c23b1ad869653bc818e972b7a3a79852d0e494e9ab7e1a701a3decc49c20d51"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15b09b06dae900777833fe7fc4b4aa426556ce95847a3e8d7548e2d19e34edb8"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:477c3ea0ba410b2b56b7efb072c36fa91b1e6fc331761798fa3f28bb224830dd"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2f2f69dca064926e79997f45b2f34e202b320fd3782f17a91941f7eb85502ee2"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ef9612483cb35171d51d9173647eed5d0069eaa2ee812793a75373447d487aa4"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6d69f36d445c45cda7b3b26afef2fc34ef5ac0cdc75584a87ef307ee3c8c6d00"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:55c3d1072704d27401c92339144d199d9de7b52627f724a949fc7d5fc56d8b93"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b9d00268fcb9f66fbcc7cd9fe423741d90c75ee029a1d15c09b22d23253c0a44"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:07b05cd3305e8a73112103c834e91cd27ce5b4bd07850c4b4dbd1877d3f45be7"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c34dc4958b232ef6188c4318cb7b2c2d80521c9a56c52449f8f93ab7bc2a8a1c"}, - {file = "aiohttp-3.8.1-cp37-cp37m-win32.whl", hash = "sha256:d2f9b69293c33aaa53d923032fe227feac867f81682f002ce33ffae978f0a9a9"}, - {file = "aiohttp-3.8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6ae828d3a003f03ae31915c31fa684b9890ea44c9c989056fea96e3d12a9fa17"}, - {file = "aiohttp-3.8.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0c7ebbbde809ff4e970824b2b6cb7e4222be6b95a296e46c03cf050878fc1785"}, - {file = "aiohttp-3.8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b7ef7cbd4fec9a1e811a5de813311ed4f7ac7d93e0fda233c9b3e1428f7dd7b"}, - {file = "aiohttp-3.8.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c3d6a4d0619e09dcd61021debf7059955c2004fa29f48788a3dfaf9c9901a7cd"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:718626a174e7e467f0558954f94af117b7d4695d48eb980146016afa4b580b2e"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:589c72667a5febd36f1315aa6e5f56dd4aa4862df295cb51c769d16142ddd7cd"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ed076098b171573161eb146afcb9129b5ff63308960aeca4b676d9d3c35e700"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:086f92daf51a032d062ec5f58af5ca6a44d082c35299c96376a41cbb33034675"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:11691cf4dc5b94236ccc609b70fec991234e7ef8d4c02dd0c9668d1e486f5abf"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:31d1e1c0dbf19ebccbfd62eff461518dcb1e307b195e93bba60c965a4dcf1ba0"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:11a67c0d562e07067c4e86bffc1553f2cf5b664d6111c894671b2b8712f3aba5"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:bb01ba6b0d3f6c68b89fce7305080145d4877ad3acaed424bae4d4ee75faa950"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:44db35a9e15d6fe5c40d74952e803b1d96e964f683b5a78c3cc64eb177878155"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:844a9b460871ee0a0b0b68a64890dae9c415e513db0f4a7e3cab41a0f2fedf33"}, - {file = "aiohttp-3.8.1-cp38-cp38-win32.whl", hash = "sha256:7d08744e9bae2ca9c382581f7dce1273fe3c9bae94ff572c3626e8da5b193c6a"}, - {file = "aiohttp-3.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:04d48b8ce6ab3cf2097b1855e1505181bdd05586ca275f2505514a6e274e8e75"}, - {file = "aiohttp-3.8.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f5315a2eb0239185af1bddb1abf472d877fede3cc8d143c6cddad37678293237"}, - {file = "aiohttp-3.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a996d01ca39b8dfe77440f3cd600825d05841088fd6bc0144cc6c2ec14cc5f74"}, - {file = "aiohttp-3.8.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:13487abd2f761d4be7c8ff9080de2671e53fff69711d46de703c310c4c9317ca"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea302f34477fda3f85560a06d9ebdc7fa41e82420e892fc50b577e35fc6a50b2"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2f635ce61a89c5732537a7896b6319a8fcfa23ba09bec36e1b1ac0ab31270d2"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e999f2d0e12eea01caeecb17b653f3713d758f6dcc770417cf29ef08d3931421"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0770e2806a30e744b4e21c9d73b7bee18a1cfa3c47991ee2e5a65b887c49d5cf"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d15367ce87c8e9e09b0f989bfd72dc641bcd04ba091c68cd305312d00962addd"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6c7cefb4b0640703eb1069835c02486669312bf2f12b48a748e0a7756d0de33d"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:71927042ed6365a09a98a6377501af5c9f0a4d38083652bcd2281a06a5976724"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:28d490af82bc6b7ce53ff31337a18a10498303fe66f701ab65ef27e143c3b0ef"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b6613280ccedf24354406caf785db748bebbddcf31408b20c0b48cb86af76866"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81e3d8c34c623ca4e36c46524a3530e99c0bc95ed068fd6e9b55cb721d408fb2"}, - {file = "aiohttp-3.8.1-cp39-cp39-win32.whl", hash = "sha256:7187a76598bdb895af0adbd2fb7474d7f6025d170bc0a1130242da817ce9e7d1"}, - {file = "aiohttp-3.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:1c182cb873bc91b411e184dab7a2b664d4fea2743df0e4d57402f7f3fa644bac"}, - {file = "aiohttp-3.8.1.tar.gz", hash = "sha256:fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578"}, -] -aiosignal = [ - {file = "aiosignal-1.2.0-py3-none-any.whl", hash = "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a"}, - {file = "aiosignal-1.2.0.tar.gz", hash = "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2"}, -] -asttokens = [ - {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"}, - {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"}, -] -async-timeout = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, -] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, -] -attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, -] -base58 = [ - {file = "base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2"}, - {file = "base58-2.1.1.tar.gz", hash = "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c"}, -] -bitarray = [ - {file = "bitarray-1.2.2.tar.gz", hash = "sha256:27a69ffcee3b868abab3ce8b17c69e02b63e722d4d64ffd91d659f81e9984954"}, -] -black = [ - {file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"}, - {file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"}, - {file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"}, - {file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"}, - {file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"}, - {file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"}, - {file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"}, - {file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"}, - {file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"}, - {file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"}, - {file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"}, - {file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"}, - {file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"}, - {file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"}, - {file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"}, - {file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"}, - {file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"}, - {file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"}, - {file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"}, - {file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"}, - {file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"}, - {file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"}, - {file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"}, -] -certifi = [ - {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, - {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.0.11.tar.gz", hash = "sha256:98398a9d69ee80548c762ba991a4728bfc3836768ed226b3945908d1a688371c"}, - {file = "charset_normalizer-2.0.11-py3-none-any.whl", hash = "sha256:2842d8f5e82a1f6aa437380934d5e1cd4fcf2003b06fed6940769c164a480a45"}, -] -click = [ - {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, - {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, -] -colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, -] -cytoolz = [ - {file = "cytoolz-0.11.2.tar.gz", hash = "sha256:ea23663153806edddce7e4153d1d407d62357c05120a4e8485bddf1bd5ab22b4"}, -] -dataclassy = [ - {file = "dataclassy-0.11.1-py3-none-any.whl", hash = "sha256:bcb030d3d700cf9b1597042bbc8375b92773e6f68f65675a7071862c0ddb87f5"}, - {file = "dataclassy-0.11.1.tar.gz", hash = "sha256:ad6622cb91e644d13f68768558983fbc22c90a8ff7e355638485d18b9baf1198"}, -] -eip712 = [ - {file = "eip712-0.1.0-py3-none-any.whl", hash = "sha256:8d91257bb94cc33b0115b2f65c71297b6e8b8f16ed49173313e13ac8931df4b1"}, - {file = "eip712-0.1.0.tar.gz", hash = "sha256:2655c8ab58a552bc2adf0b5a07465483fe24a27237e07c4384f36f16efafa418"}, -] -eth-abi = [ - {file = "eth_abi-2.1.1-py3-none-any.whl", hash = "sha256:78df5d2758247a8f0766a7cfcea4575bcfe568c34a33e6d05a72c328a9040444"}, - {file = "eth_abi-2.1.1.tar.gz", hash = "sha256:4bb1d87bb6605823379b07f6c02c8af45df01a27cc85bd6abb7cf1446ce7d188"}, -] -eth-account = [ - {file = "eth-account-0.5.7.tar.gz", hash = "sha256:c86b59ff92f1bb14dea2632c2df657be6a98c450cfe24e2536fb69b6207364e7"}, - {file = "eth_account-0.5.7-py3-none-any.whl", hash = "sha256:a82ff2500d7e7a54535ec3d4ea0a58feaf6e94f3ff65ae999f2a508e9b2e1ec1"}, -] -eth-brownie = [ - {file = "eth-brownie-1.18.1.tar.gz", hash = "sha256:0f51881237bd38752bcd35a7c248b110eacc1cf7c2d8ccba808ea691a90688eb"}, - {file = "eth_brownie-1.18.1-py3-none-any.whl", hash = "sha256:a6f3cd1d0ff2f09ccb01117b30bb1c33a49aa2880d4a0c7c6e0acf5c73e7e06e"}, -] -eth-event = [ - {file = "eth-event-1.2.3.tar.gz", hash = "sha256:1589b583a9b0294f9aba4dedce8077685ced298393872f7f19bbf7d67ed9e49a"}, - {file = "eth_event-1.2.3-py3-none-any.whl", hash = "sha256:5d86d049eded86d0fb41538590487e1ccea2e1fa3e6d16ee2fc0952be7e5c59a"}, -] -eth-hash = [ - {file = "eth-hash-0.3.2.tar.gz", hash = "sha256:3f40cecd5ead88184aa9550afc19d057f103728108c5102f592f8415949b5a76"}, - {file = "eth_hash-0.3.2-py3-none-any.whl", hash = "sha256:de7385148a8e0237ba1240cddbc06d53f56731140f8593bdb8429306f6b42271"}, -] -eth-keyfile = [ - {file = "eth-keyfile-0.5.1.tar.gz", hash = "sha256:939540efb503380bc30d926833e6a12b22c6750de80feef3720d79e5a79de47d"}, - {file = "eth_keyfile-0.5.1-py3-none-any.whl", hash = "sha256:70d734af17efdf929a90bb95375f43522be4ed80c3b9e0a8bca575fb11cd1159"}, -] -eth-keys = [ - {file = "eth-keys-0.3.4.tar.gz", hash = "sha256:e5590797f5e2930086c705a6dd1ac14397f74f19bdcd1b5f837475554f354ad8"}, - {file = "eth_keys-0.3.4-py3-none-any.whl", hash = "sha256:565bf62179b8143bcbd302a0ec6c49882d9c7678f9e6ab0484a8a5725f5ef10e"}, -] -eth-rlp = [ - {file = "eth-rlp-0.2.1.tar.gz", hash = "sha256:f016f980b0ed42ee7650ba6e4e4d3c4e9aa06d8b9c6825a36d3afe5aa0187a8b"}, - {file = "eth_rlp-0.2.1-py3-none-any.whl", hash = "sha256:cc389ef8d7b6f76a98f90bcdbff1b8684b3a78f53d47e871191b50d4d6aee5a1"}, -] -eth-typing = [ - {file = "eth-typing-2.3.0.tar.gz", hash = "sha256:39cce97f401f082739b19258dfa3355101c64390914c73fe2b90012f443e0dc7"}, - {file = "eth_typing-2.3.0-py3-none-any.whl", hash = "sha256:b7fa58635c1cb0cbf538b2f5f1e66139575ea4853eac1d6000f0961a4b277422"}, -] -eth-utils = [ - {file = "eth-utils-1.10.0.tar.gz", hash = "sha256:bf82762a46978714190b0370265a7148c954d3f0adaa31c6f085ea375e4c61af"}, - {file = "eth_utils-1.10.0-py3-none-any.whl", hash = "sha256:74240a8c6f652d085ed3c85f5f1654203d2f10ff9062f83b3bad0a12ff321c7a"}, -] -execnet = [ - {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, - {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, -] -frozenlist = [ - {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3"}, - {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b"}, - {file = "frozenlist-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:45334234ec30fc4ea677f43171b18a27505bfb2dba9aca4398a62692c0ea8868"}, - {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47be22dc27ed933d55ee55845d34a3e4e9f6fee93039e7f8ebadb0c2f60d403f"}, - {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03a7dd1bfce30216a3f51a84e6dd0e4a573d23ca50f0346634916ff105ba6e6b"}, - {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:691ddf6dc50480ce49f68441f1d16a4c3325887453837036e0fb94736eae1e58"}, - {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bde99812f237f79eaf3f04ebffd74f6718bbd216101b35ac7955c2d47c17da02"}, - {file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a202458d1298ced3768f5a7d44301e7c86defac162ace0ab7434c2e961166e8"}, - {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9e3e9e365991f8cc5f5edc1fd65b58b41d0514a6a7ad95ef5c7f34eb49b3d3e"}, - {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:04cb491c4b1c051734d41ea2552fde292f5f3a9c911363f74f39c23659c4af78"}, - {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:436496321dad302b8b27ca955364a439ed1f0999311c393dccb243e451ff66aa"}, - {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:754728d65f1acc61e0f4df784456106e35afb7bf39cfe37227ab00436fb38676"}, - {file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6eb275c6385dd72594758cbe96c07cdb9bd6becf84235f4a594bdf21e3596c9d"}, - {file = "frozenlist-1.3.0-cp310-cp310-win32.whl", hash = "sha256:e30b2f9683812eb30cf3f0a8e9f79f8d590a7999f731cf39f9105a7c4a39489d"}, - {file = "frozenlist-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f7353ba3367473d1d616ee727945f439e027f0bb16ac1a750219a8344d1d5d3c"}, - {file = "frozenlist-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88aafd445a233dbbf8a65a62bc3249a0acd0d81ab18f6feb461cc5a938610d24"}, - {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4406cfabef8f07b3b3af0f50f70938ec06d9f0fc26cbdeaab431cbc3ca3caeaa"}, - {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf829bd2e2956066dd4de43fd8ec881d87842a06708c035b37ef632930505a2"}, - {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:603b9091bd70fae7be28bdb8aa5c9990f4241aa33abb673390a7f7329296695f"}, - {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25af28b560e0c76fa41f550eacb389905633e7ac02d6eb3c09017fa1c8cdfde1"}, - {file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c7a8a9fc9383b52c410a2ec952521906d355d18fccc927fca52ab575ee8b93"}, - {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:65bc6e2fece04e2145ab6e3c47428d1bbc05aede61ae365b2c1bddd94906e478"}, - {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3f7c935c7b58b0d78c0beea0c7358e165f95f1fd8a7e98baa40d22a05b4a8141"}, - {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd89acd1b8bb4f31b47072615d72e7f53a948d302b7c1d1455e42622de180eae"}, - {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6983a31698490825171be44ffbafeaa930ddf590d3f051e397143a5045513b01"}, - {file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:adac9700675cf99e3615eb6a0eb5e9f5a4143c7d42c05cea2e7f71c27a3d0846"}, - {file = "frozenlist-1.3.0-cp37-cp37m-win32.whl", hash = "sha256:0c36e78b9509e97042ef869c0e1e6ef6429e55817c12d78245eb915e1cca7468"}, - {file = "frozenlist-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:57f4d3f03a18facacb2a6bcd21bccd011e3b75d463dc49f838fd699d074fabd1"}, - {file = "frozenlist-1.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8c905a5186d77111f02144fab5b849ab524f1e876a1e75205cd1386a9be4b00a"}, - {file = "frozenlist-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5009062d78a8c6890d50b4e53b0ddda31841b3935c1937e2ed8c1bda1c7fb9d"}, - {file = "frozenlist-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2fdc3cd845e5a1f71a0c3518528bfdbfe2efaf9886d6f49eacc5ee4fd9a10953"}, - {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92e650bd09b5dda929523b9f8e7f99b24deac61240ecc1a32aeba487afcd970f"}, - {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:40dff8962b8eba91fd3848d857203f0bd704b5f1fa2b3fc9af64901a190bba08"}, - {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:768efd082074bb203c934e83a61654ed4931ef02412c2fbdecea0cff7ecd0274"}, - {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:006d3595e7d4108a12025ddf415ae0f6c9e736e726a5db0183326fd191b14c5e"}, - {file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:871d42623ae15eb0b0e9df65baeee6976b2e161d0ba93155411d58ff27483ad8"}, - {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aff388be97ef2677ae185e72dc500d19ecaf31b698986800d3fc4f399a5e30a5"}, - {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f892d6a94ec5c7b785e548e42722e6f3a52f5f32a8461e82ac3e67a3bd073f1"}, - {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:e982878792c971cbd60ee510c4ee5bf089a8246226dea1f2138aa0bb67aff148"}, - {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c6c321dd013e8fc20735b92cb4892c115f5cdb82c817b1e5b07f6b95d952b2f0"}, - {file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:30530930410855c451bea83f7b272fb1c495ed9d5cc72895ac29e91279401db3"}, - {file = "frozenlist-1.3.0-cp38-cp38-win32.whl", hash = "sha256:40ec383bc194accba825fbb7d0ef3dda5736ceab2375462f1d8672d9f6b68d07"}, - {file = "frozenlist-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:f20baa05eaa2bcd5404c445ec51aed1c268d62600362dc6cfe04fae34a424bd9"}, - {file = "frozenlist-1.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0437fe763fb5d4adad1756050cbf855bbb2bf0d9385c7bb13d7a10b0dd550486"}, - {file = "frozenlist-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b684c68077b84522b5c7eafc1dc735bfa5b341fb011d5552ebe0968e22ed641c"}, - {file = "frozenlist-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93641a51f89473837333b2f8100f3f89795295b858cd4c7d4a1f18e299dc0a4f"}, - {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6d32ff213aef0fd0bcf803bffe15cfa2d4fde237d1d4838e62aec242a8362fa"}, - {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31977f84828b5bb856ca1eb07bf7e3a34f33a5cddce981d880240ba06639b94d"}, - {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c62964192a1c0c30b49f403495911298810bada64e4f03249ca35a33ca0417a"}, - {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4eda49bea3602812518765810af732229b4291d2695ed24a0a20e098c45a707b"}, - {file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acb267b09a509c1df5a4ca04140da96016f40d2ed183cdc356d237286c971b51"}, - {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e1e26ac0a253a2907d654a37e390904426d5ae5483150ce3adedb35c8c06614a"}, - {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f96293d6f982c58ebebb428c50163d010c2f05de0cde99fd681bfdc18d4b2dc2"}, - {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e84cb61b0ac40a0c3e0e8b79c575161c5300d1d89e13c0e02f76193982f066ed"}, - {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:ff9310f05b9d9c5c4dd472983dc956901ee6cb2c3ec1ab116ecdde25f3ce4951"}, - {file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d26b650b71fdc88065b7a21f8ace70175bcf3b5bdba5ea22df4bfd893e795a3b"}, - {file = "frozenlist-1.3.0-cp39-cp39-win32.whl", hash = "sha256:01a73627448b1f2145bddb6e6c2259988bb8aee0fb361776ff8604b99616cd08"}, - {file = "frozenlist-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab"}, - {file = "frozenlist-1.3.0.tar.gz", hash = "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b"}, -] -hexbytes = [ - {file = "hexbytes-0.2.2-py3-none-any.whl", hash = "sha256:ef53c37ea9f316fff86fcb1df057b4c6ba454da348083e972031bbf7bc9c3acc"}, - {file = "hexbytes-0.2.2.tar.gz", hash = "sha256:a5881304d186e87578fb263a85317c808cf130e1d4b3d37d30142ab0f7898d03"}, -] -hypothesis = [ - {file = "hypothesis-6.27.3-py3-none-any.whl", hash = "sha256:1c4568f40ca893c884330a1de0e0e5dcb1e867c60a56f414cb7bce97afc8dfec"}, - {file = "hypothesis-6.27.3.tar.gz", hash = "sha256:587da483bcc324494cec09cbbde3396c00da280c1732e387d7b5b89eff1aaff3"}, -] -idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, -] -inflection = [ - {file = "inflection-0.5.0-py2.py3-none-any.whl", hash = "sha256:88b101b2668a1d81d6d72d4c2018e53bc6c7fc544c987849da1c7f77545c3bc9"}, - {file = "inflection-0.5.0.tar.gz", hash = "sha256:f576e85132d34f5bf7df5183c2c6f94cfb32e528f53065345cf71329ba0b8924"}, -] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -ipfshttpclient = [ - {file = "ipfshttpclient-0.8.0a2-py3-none-any.whl", hash = "sha256:ce6bac0e3963c4ced74d7eb6978125362bb05bbe219088ca48f369ce14d3cc39"}, - {file = "ipfshttpclient-0.8.0a2.tar.gz", hash = "sha256:0d80e95ee60b02c7d414e79bf81a36fc3c8fbab74265475c52f70b2620812135"}, -] -jsonschema = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] -lazy-object-proxy = [ - {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, - {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, -] -lru-dict = [ - {file = "lru-dict-1.1.7.tar.gz", hash = "sha256:45b81f67d75341d4433abade799a47e9c42a9e22a118531dcb5e549864032d7c"}, -] -multiaddr = [ - {file = "multiaddr-0.0.9-py2.py3-none-any.whl", hash = "sha256:5c0f862cbcf19aada2a899f80ef896ddb2e85614e0c8f04dd287c06c69dac95b"}, - {file = "multiaddr-0.0.9.tar.gz", hash = "sha256:30b2695189edc3d5b90f1c303abb8f02d963a3a4edf2e7178b975eb417ab0ecf"}, -] -multidict = [ - {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"}, - {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"}, - {file = "multidict-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88"}, - {file = "multidict-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87"}, - {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389"}, - {file = "multidict-6.0.2-cp310-cp310-win32.whl", hash = "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293"}, - {file = "multidict-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658"}, - {file = "multidict-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b"}, - {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b"}, - {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15"}, - {file = "multidict-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc"}, - {file = "multidict-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a"}, - {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60"}, - {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86"}, - {file = "multidict-6.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693"}, - {file = "multidict-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9"}, - {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d"}, - {file = "multidict-6.0.2-cp38-cp38-win32.whl", hash = "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57"}, - {file = "multidict-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96"}, - {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c"}, - {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e"}, - {file = "multidict-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9"}, - {file = "multidict-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360"}, - {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937"}, - {file = "multidict-6.0.2-cp39-cp39-win32.whl", hash = "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a"}, - {file = "multidict-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae"}, - {file = "multidict-6.0.2.tar.gz", hash = "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013"}, -] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -mythx-models = [ - {file = "mythx-models-1.9.1.tar.gz", hash = "sha256:037090723c5006df25656473db7875469e11d9d03478d41bb8d1f1517c1c474c"}, - {file = "mythx_models-1.9.1-py2.py3-none-any.whl", hash = "sha256:4b9133c2ee41f97c03545bb480a16f3388b10557c5622aeada7ce79aaadcf7de"}, -] -netaddr = [ - {file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"}, - {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, -] -packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, -] -parsimonious = [ - {file = "parsimonious-0.8.1.tar.gz", hash = "sha256:3add338892d580e0cb3b1a39e4a1b427ff9f687858fdd61097053742391a9f6b"}, -] -pathspec = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, -] -platformdirs = [ - {file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"}, - {file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"}, -] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -prompt-toolkit = [ - {file = "prompt_toolkit-3.0.26-py3-none-any.whl", hash = "sha256:4bcf119be2200c17ed0d518872ef922f1de336eb6d1ddbd1e089ceb6447d97c6"}, - {file = "prompt_toolkit-3.0.26.tar.gz", hash = "sha256:a51d41a6a45fd9def54365bca8f0402c8f182f2b6f7e29c74d55faeb9fb38ac4"}, -] -protobuf = [ - {file = "protobuf-3.19.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37"}, - {file = "protobuf-3.19.4-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb"}, - {file = "protobuf-3.19.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c"}, - {file = "protobuf-3.19.4-cp310-cp310-win32.whl", hash = "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0"}, - {file = "protobuf-3.19.4-cp310-cp310-win_amd64.whl", hash = "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07"}, - {file = "protobuf-3.19.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4"}, - {file = "protobuf-3.19.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f"}, - {file = "protobuf-3.19.4-cp36-cp36m-win32.whl", hash = "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee"}, - {file = "protobuf-3.19.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b"}, - {file = "protobuf-3.19.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13"}, - {file = "protobuf-3.19.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368"}, - {file = "protobuf-3.19.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909"}, - {file = "protobuf-3.19.4-cp37-cp37m-win32.whl", hash = "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9"}, - {file = "protobuf-3.19.4-cp37-cp37m-win_amd64.whl", hash = "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f"}, - {file = "protobuf-3.19.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2"}, - {file = "protobuf-3.19.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2"}, - {file = "protobuf-3.19.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7"}, - {file = "protobuf-3.19.4-cp38-cp38-win32.whl", hash = "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26"}, - {file = "protobuf-3.19.4-cp38-cp38-win_amd64.whl", hash = "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e"}, - {file = "protobuf-3.19.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58"}, - {file = "protobuf-3.19.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934"}, - {file = "protobuf-3.19.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e"}, - {file = "protobuf-3.19.4-cp39-cp39-win32.whl", hash = "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a"}, - {file = "protobuf-3.19.4-cp39-cp39-win_amd64.whl", hash = "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca"}, - {file = "protobuf-3.19.4-py2.py3-none-any.whl", hash = "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616"}, - {file = "protobuf-3.19.4.tar.gz", hash = "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a"}, -] -psutil = [ - {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b"}, - {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618"}, - {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2"}, - {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd"}, - {file = "psutil-5.9.0-cp27-none-win32.whl", hash = "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3"}, - {file = "psutil-5.9.0-cp27-none-win_amd64.whl", hash = "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c"}, - {file = "psutil-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492"}, - {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3"}, - {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2"}, - {file = "psutil-5.9.0-cp310-cp310-win32.whl", hash = "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d"}, - {file = "psutil-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b"}, - {file = "psutil-5.9.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56"}, - {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203"}, - {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d"}, - {file = "psutil-5.9.0-cp36-cp36m-win32.whl", hash = "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64"}, - {file = "psutil-5.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94"}, - {file = "psutil-5.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0"}, - {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce"}, - {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5"}, - {file = "psutil-5.9.0-cp37-cp37m-win32.whl", hash = "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9"}, - {file = "psutil-5.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4"}, - {file = "psutil-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2"}, - {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d"}, - {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a"}, - {file = "psutil-5.9.0-cp38-cp38-win32.whl", hash = "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666"}, - {file = "psutil-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841"}, - {file = "psutil-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf"}, - {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07"}, - {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d"}, - {file = "psutil-5.9.0-cp39-cp39-win32.whl", hash = "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845"}, - {file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"}, - {file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"}, -] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] -py-solc-ast = [ - {file = "py-solc-ast-1.2.9.tar.gz", hash = "sha256:5a5c3bb1998de32eed4b793ebbf2f14f1fd5c681cf8b62af6b8f9f76b805164d"}, - {file = "py_solc_ast-1.2.9-py3-none-any.whl", hash = "sha256:f636217ef77bbe0f9c87a71af2f6cc9577f6301aa2ffb9af119f4c8fa8522b2d"}, -] -py-solc-x = [ - {file = "py-solc-x-1.1.1.tar.gz", hash = "sha256:d8b0bd2b04f47cff6e92181739d9e94e41b2d62f056900761c797fa5babc76b6"}, - {file = "py_solc_x-1.1.1-py3-none-any.whl", hash = "sha256:8f5caa4f54e227fc301e2e4c8aa868e869c2bc0c6636aa9e8115f8414bb891f9"}, -] -pycryptodome = [ - {file = "pycryptodome-3.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:75a3a364fee153e77ed889c957f6f94ec6d234b82e7195b117180dcc9fc16f96"}, - {file = "pycryptodome-3.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:aae395f79fa549fb1f6e3dc85cf277f0351e15a22e6547250056c7f0c990d6a5"}, - {file = "pycryptodome-3.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f403a3e297a59d94121cb3ee4b1cf41f844332940a62d71f9e4a009cc3533493"}, - {file = "pycryptodome-3.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ce7a875694cd6ccd8682017a7c06c6483600f151d8916f2b25cf7a439e600263"}, - {file = "pycryptodome-3.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a36ab51674b014ba03da7f98b675fcb8eabd709a2d8e18219f784aba2db73b72"}, - {file = "pycryptodome-3.14.1-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:50a5346af703330944bea503106cd50c9c2212174cfcb9939db4deb5305a8367"}, - {file = "pycryptodome-3.14.1-cp27-cp27m-win32.whl", hash = "sha256:36e3242c4792e54ed906c53f5d840712793dc68b726ec6baefd8d978c5282d30"}, - {file = "pycryptodome-3.14.1-cp27-cp27m-win_amd64.whl", hash = "sha256:c880a98376939165b7dc504559f60abe234b99e294523a273847f9e7756f4132"}, - {file = "pycryptodome-3.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:dcd65355acba9a1d0fc9b923875da35ed50506e339b35436277703d7ace3e222"}, - {file = "pycryptodome-3.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:766a8e9832128c70012e0c2b263049506cbf334fb21ff7224e2704102b6ef59e"}, - {file = "pycryptodome-3.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:2562de213960693b6d657098505fd4493c45f3429304da67efcbeb61f0edfe89"}, - {file = "pycryptodome-3.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d1b7739b68a032ad14c5e51f7e4e1a5f92f3628bba024a2bda1f30c481fc85d8"}, - {file = "pycryptodome-3.14.1-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:27e92c1293afcb8d2639baf7eb43f4baada86e4de0f1fb22312bfc989b95dae2"}, - {file = "pycryptodome-3.14.1-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f2772af1c3ef8025c85335f8b828d0193fa1e43256621f613280e2c81bfad423"}, - {file = "pycryptodome-3.14.1-cp35-abi3-manylinux1_i686.whl", hash = "sha256:9ec761a35dbac4a99dcbc5cd557e6e57432ddf3e17af8c3c86b44af9da0189c0"}, - {file = "pycryptodome-3.14.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:e64738207a02a83590df35f59d708bf1e7ea0d6adce712a777be2967e5f7043c"}, - {file = "pycryptodome-3.14.1-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:e24d4ec4b029611359566c52f31af45c5aecde7ef90bf8f31620fd44c438efe7"}, - {file = "pycryptodome-3.14.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:8b5c28058102e2974b9868d72ae5144128485d466ba8739abd674b77971454cc"}, - {file = "pycryptodome-3.14.1-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:924b6aad5386fb54f2645f22658cb0398b1f25bc1e714a6d1522c75d527deaa5"}, - {file = "pycryptodome-3.14.1-cp35-abi3-win32.whl", hash = "sha256:53dedbd2a6a0b02924718b520a723e88bcf22e37076191eb9b91b79934fb2192"}, - {file = "pycryptodome-3.14.1-cp35-abi3-win_amd64.whl", hash = "sha256:ea56a35fd0d13121417d39a83f291017551fa2c62d6daa6b04af6ece7ed30d84"}, - {file = "pycryptodome-3.14.1-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:028dcbf62d128b4335b61c9fbb7dd8c376594db607ef36d5721ee659719935d5"}, - {file = "pycryptodome-3.14.1-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:69f05aaa90c99ac2f2af72d8d7f185f729721ad7c4be89e9e3d0ab101b0ee875"}, - {file = "pycryptodome-3.14.1-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:12ef157eb1e01a157ca43eda275fa68f8db0dd2792bc4fe00479ab8f0e6ae075"}, - {file = "pycryptodome-3.14.1-pp27-pypy_73-win32.whl", hash = "sha256:f572a3ff7b6029dd9b904d6be4e0ce9e309dcb847b03e3ac8698d9d23bb36525"}, - {file = "pycryptodome-3.14.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9924248d6920b59c260adcae3ee231cd5af404ac706ad30aa4cd87051bf09c50"}, - {file = "pycryptodome-3.14.1-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:e0c04c41e9ade19fbc0eff6aacea40b831bfcb2c91c266137bcdfd0d7b2f33ba"}, - {file = "pycryptodome-3.14.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:893f32210de74b9f8ac869ed66c97d04e7d351182d6d39ebd3b36d3db8bda65d"}, - {file = "pycryptodome-3.14.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:7fb90a5000cc9c9ff34b4d99f7f039e9c3477700e309ff234eafca7b7471afc0"}, - {file = "pycryptodome-3.14.1.tar.gz", hash = "sha256:e04e40a7f8c1669195536a37979dd87da2c32dbdc73d6fe35f0077b0c17c803b"}, -] -pygments = [ - {file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"}, - {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, -] -pygments-lexer-solidity = [ - {file = "pygments-lexer-solidity-0.7.0.tar.gz", hash = "sha256:a347fd96981838331b6d98b0f891776908a49406d343ff2a40a6a1c8475a9350"}, -] -pyjwt = [ - {file = "PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e"}, - {file = "PyJWT-1.7.1.tar.gz", hash = "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"}, -] -pyparsing = [ - {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, - {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, -] -pyrsistent = [ - {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, - {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, - {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, - {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, -] -pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] -pytest-forked = [ - {file = "pytest-forked-1.4.0.tar.gz", hash = "sha256:8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e"}, - {file = "pytest_forked-1.4.0-py3-none-any.whl", hash = "sha256:bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8"}, -] -pytest-xdist = [ - {file = "pytest-xdist-1.34.0.tar.gz", hash = "sha256:340e8e83e2a4c0d861bdd8d05c5d7b7143f6eea0aba902997db15c2a86be04ee"}, - {file = "pytest_xdist-1.34.0-py2.py3-none-any.whl", hash = "sha256:ba5d10729372d65df3ac150872f9df5d2ed004a3b0d499cc0164aafedd8c7b66"}, -] -python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, -] -python-dotenv = [ - {file = "python-dotenv-0.16.0.tar.gz", hash = "sha256:9fa413c37d4652d3fa02fea0ff465c384f5db75eab259c4fc5d0c5b8bf20edd4"}, - {file = "python_dotenv-0.16.0-py2.py3-none-any.whl", hash = "sha256:31d752f5b748f4e292448c9a0cac6a08ed5e6f4cefab85044462dcad56905cec"}, -] -pythx = [ - {file = "pythx-1.6.1-py2.py3-none-any.whl", hash = "sha256:44cb6c88f5213a3dd516e8322dbd17551fc7d435dc6290d3a6145333258d901f"}, - {file = "pythx-1.6.1.tar.gz", hash = "sha256:7758a00125d5ba96d902bd2c79c1b1d10713a86479dc4f9ea7febc2337ff1eca"}, -] -pywin32 = [ - {file = "pywin32-303-cp310-cp310-win32.whl", hash = "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb"}, - {file = "pywin32-303-cp310-cp310-win_amd64.whl", hash = "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51"}, - {file = "pywin32-303-cp311-cp311-win32.whl", hash = "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee"}, - {file = "pywin32-303-cp311-cp311-win_amd64.whl", hash = "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439"}, - {file = "pywin32-303-cp36-cp36m-win32.whl", hash = "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9"}, - {file = "pywin32-303-cp36-cp36m-win_amd64.whl", hash = "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559"}, - {file = "pywin32-303-cp37-cp37m-win32.whl", hash = "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e"}, - {file = "pywin32-303-cp37-cp37m-win_amd64.whl", hash = "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca"}, - {file = "pywin32-303-cp38-cp38-win32.whl", hash = "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b"}, - {file = "pywin32-303-cp38-cp38-win_amd64.whl", hash = "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba"}, - {file = "pywin32-303-cp39-cp39-win32.whl", hash = "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352"}, - {file = "pywin32-303-cp39-cp39-win_amd64.whl", hash = "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34"}, -] -pyyaml = [ - {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, - {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, - {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, - {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, - {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, - {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, - {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, - {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, - {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, -] -requests = [ - {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, - {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, -] -rlp = [ - {file = "rlp-2.0.1-py2.py3-none-any.whl", hash = "sha256:52a57c9f53f03c88b189283734b397314288250cc4a3c4113e9e36e2ac6bdd16"}, - {file = "rlp-2.0.1.tar.gz", hash = "sha256:665e8312750b3fc5f7002e656d05b9dcb6e93b6063df40d95c49ad90c19d1f0e"}, -] -semantic-version = [ - {file = "semantic_version-2.8.5-py2.py3-none-any.whl", hash = "sha256:45e4b32ee9d6d70ba5f440ec8cc5221074c7f4b0e8918bdab748cc37912440a9"}, - {file = "semantic_version-2.8.5.tar.gz", hash = "sha256:d2cb2de0558762934679b9a104e82eca7af448c9f4974d1f3eeccff651df8a54"}, -] -setuptools = [ - {file = "setuptools-62.0.0-py3-none-any.whl", hash = "sha256:a65e3802053e99fc64c6b3b29c11132943d5b8c8facbcc461157511546510967"}, - {file = "setuptools-62.0.0.tar.gz", hash = "sha256:7999cbd87f1b6e1f33bf47efa368b224bed5e27b5ef2c4d46580186cbcb1a86a"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -sortedcontainers = [ - {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, - {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, -] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tomli = [ - {file = "tomli-2.0.0-py3-none-any.whl", hash = "sha256:b5bde28da1fed24b9bd1d4d2b8cba62300bfb4ec9a6187a957e8ddb9434c5224"}, - {file = "tomli-2.0.0.tar.gz", hash = "sha256:c292c34f58502a1eb2bbb9f5bbc9a5ebc37bee10ffb8c2d6bbdfa8eb13cc14e1"}, -] -toolz = [ - {file = "toolz-0.11.2-py3-none-any.whl", hash = "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f"}, - {file = "toolz-0.11.2.tar.gz", hash = "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33"}, -] -tqdm = [ - {file = "tqdm-4.62.3-py2.py3-none-any.whl", hash = "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c"}, - {file = "tqdm-4.62.3.tar.gz", hash = "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"}, -] -typing-extensions = [ - {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, - {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, -] -urllib3 = [ - {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, - {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, -] -varint = [ - {file = "varint-1.0.2.tar.gz", hash = "sha256:a6ecc02377ac5ee9d65a6a8ad45c9ff1dac8ccee19400a5950fb51d594214ca5"}, -] -vvm = [ - {file = "vvm-0.1.0-py3-none-any.whl", hash = "sha256:814c67bc8049d45ea8049bc26b04ce4065015f5a3e2896a1a2a2a44ab6e85edc"}, - {file = "vvm-0.1.0.tar.gz", hash = "sha256:a1474915b12e0084299d2c7fe7d72434fa99c00ebb117e400756a5d7e0edac2a"}, -] -vyper = [ - {file = "vyper-0.3.1-py3-none-any.whl", hash = "sha256:40eabebb0cf859f9660ad94d3af273d3176252d50597fdb94fa808446943d1c5"}, - {file = "vyper-0.3.1.tar.gz", hash = "sha256:7d7ba0e6fdf3b2dcf5f6e7b1316a241c156c7dc9766427483885ca78b57287f4"}, -] -wcwidth = [ - {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, - {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, -] -web3 = [ - {file = "web3-5.27.0-py3-none-any.whl", hash = "sha256:48cab7999c9a4474c57fac16aa36b5e68730dae6f28b59564d5726b3fb221ed7"}, - {file = "web3-5.27.0.tar.gz", hash = "sha256:e4ca28643b74365e7b50ec5db2d1be9799c14ad8d8b6ba31c0ecd3b573725bbd"}, -] -websockets = [ - {file = "websockets-9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da"}, - {file = "websockets-9.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4"}, - {file = "websockets-9.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2cf04601633a4ec176b9cc3d3e73789c037641001dbfaf7c411f89cd3e04fcaf"}, - {file = "websockets-9.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:5c8f0d82ea2468282e08b0cf5307f3ad022290ed50c45d5cb7767957ca782880"}, - {file = "websockets-9.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:caa68c95bc1776d3521f81eeb4d5b9438be92514ec2a79fececda814099c8314"}, - {file = "websockets-9.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d2c2d9b24d3c65b5a02cac12cbb4e4194e590314519ed49db2f67ef561c3cf58"}, - {file = "websockets-9.1-cp36-cp36m-win32.whl", hash = "sha256:f31722f1c033c198aa4a39a01905951c00bd1c74f922e8afc1b1c62adbcdd56a"}, - {file = "websockets-9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:3ddff38894c7857c476feb3538dd847514379d6dc844961dc99f04b0384b1b1b"}, - {file = "websockets-9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:51d04df04ed9d08077d10ccbe21e6805791b78eac49d16d30a1f1fe2e44ba0af"}, - {file = "websockets-9.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f68c352a68e5fdf1e97288d5cec9296664c590c25932a8476224124aaf90dbcd"}, - {file = "websockets-9.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:b43b13e5622c5a53ab12f3272e6f42f1ce37cd5b6684b2676cb365403295cd40"}, - {file = "websockets-9.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9147868bb0cc01e6846606cd65cbf9c58598f187b96d14dd1ca17338b08793bb"}, - {file = "websockets-9.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:836d14eb53b500fd92bd5db2fc5894f7c72b634f9c2a28f546f75967503d8e25"}, - {file = "websockets-9.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:48c222feb3ced18f3dc61168ca18952a22fb88e5eb8902d2bf1b50faefdc34a2"}, - {file = "websockets-9.1-cp37-cp37m-win32.whl", hash = "sha256:900589e19200be76dd7cbaa95e9771605b5ce3f62512d039fb3bc5da9014912a"}, - {file = "websockets-9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ab5ee15d3462198c794c49ccd31773d8a2b8c17d622aa184f669d2b98c2f0857"}, - {file = "websockets-9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85e701a6c316b7067f1e8675c638036a796fe5116783a4c932e7eb8e305a3ffe"}, - {file = "websockets-9.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b2e71c4670ebe1067fa8632f0d081e47254ee2d3d409de54168b43b0ba9147e0"}, - {file = "websockets-9.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:230a3506df6b5f446fed2398e58dcaafdff12d67fe1397dff196411a9e820d02"}, - {file = "websockets-9.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:7df3596838b2a0c07c6f6d67752c53859a54993d4f062689fdf547cb56d0f84f"}, - {file = "websockets-9.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:826ccf85d4514609219725ba4a7abd569228c2c9f1968e8be05be366f68291ec"}, - {file = "websockets-9.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0dd4eb8e0bbf365d6f652711ce21b8fd2b596f873d32aabb0fbb53ec604418cc"}, - {file = "websockets-9.1-cp38-cp38-win32.whl", hash = "sha256:1d0971cc7251aeff955aa742ec541ee8aaea4bb2ebf0245748fbec62f744a37e"}, - {file = "websockets-9.1-cp38-cp38-win_amd64.whl", hash = "sha256:7189e51955f9268b2bdd6cc537e0faa06f8fffda7fb386e5922c6391de51b077"}, - {file = "websockets-9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9e5fd6dbdf95d99bc03732ded1fc8ef22ebbc05999ac7e0c7bf57fe6e4e5ae2"}, - {file = "websockets-9.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9e7fdc775fe7403dbd8bc883ba59576a6232eac96dacb56512daacf7af5d618d"}, - {file = "websockets-9.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:597c28f3aa7a09e8c070a86b03107094ee5cdafcc0d55f2f2eac92faac8dc67d"}, - {file = "websockets-9.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:ad893d889bc700a5835e0a95a3e4f2c39e91577ab232a3dc03c262a0f8fc4b5c"}, - {file = "websockets-9.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:1d6b4fddb12ab9adf87b843cd4316c4bd602db8d5efd2fb83147f0458fe85135"}, - {file = "websockets-9.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:ebf459a1c069f9866d8569439c06193c586e72c9330db1390af7c6a0a32c4afd"}, - {file = "websockets-9.1-cp39-cp39-win32.whl", hash = "sha256:be5fd35e99970518547edc906efab29afd392319f020c3c58b0e1a158e16ed20"}, - {file = "websockets-9.1-cp39-cp39-win_amd64.whl", hash = "sha256:85db8090ba94e22d964498a47fdd933b8875a1add6ebc514c7ac8703eb97bbf0"}, - {file = "websockets-9.1.tar.gz", hash = "sha256:276d2339ebf0df4f45df453923ebd2270b87900eda5dfd4a6b0cfa15f82111c3"}, -] -wrapt = [ - {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"}, - {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"}, - {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"}, - {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"}, - {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"}, - {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"}, - {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"}, - {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"}, - {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"}, - {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"}, - {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"}, - {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"}, - {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"}, - {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"}, - {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"}, - {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"}, - {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"}, - {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"}, - {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"}, -] -yarl = [ - {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"}, - {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b"}, - {file = "yarl-1.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72"}, - {file = "yarl-1.7.2-cp310-cp310-win32.whl", hash = "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c"}, - {file = "yarl-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265"}, - {file = "yarl-1.7.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d"}, - {file = "yarl-1.7.2-cp36-cp36m-win32.whl", hash = "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1"}, - {file = "yarl-1.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913"}, - {file = "yarl-1.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b"}, - {file = "yarl-1.7.2-cp37-cp37m-win32.whl", hash = "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1"}, - {file = "yarl-1.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b"}, - {file = "yarl-1.7.2-cp38-cp38-win32.whl", hash = "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef"}, - {file = "yarl-1.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8"}, - {file = "yarl-1.7.2-cp39-cp39-win32.whl", hash = "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d"}, - {file = "yarl-1.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58"}, - {file = "yarl-1.7.2.tar.gz", hash = "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd"}, +[[package]] +name = "zipp" +version = "3.17.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, ] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.10,<3.11" +content-hash = "f9bc4e3231083cf5197911de83603e009e66e4d0f74e8aa8a2e0094c2acc4792" diff --git a/postinstall.js b/postinstall.js deleted file mode 100644 index 0e0e28b8..00000000 --- a/postinstall.js +++ /dev/null @@ -1,28 +0,0 @@ -const path = require("path"); -const copy = require("recursive-copy"); - -async function renameOpenzeppelinDependencies() { - const nodeModulesPath = path.join(__dirname, "node_modules"); - const remapping = { - "@openzeppelin/contracts": "OpenZeppelin/openzeppelin-contracts@4.3.2/contracts", - }; - - for (const localPath of Object.keys(remapping)) { - const from = path.join(nodeModulesPath, localPath); - const to = path.join(nodeModulesPath, remapping[localPath]); - try { - console.log(`Move ${localPath} to ${remapping[localPath]}`); - const res = await copy(from, to, { - overwrite: true, - expand: true, - dot: true, - junk: true, - }); - } catch (error) { - console.error(error); - process.exit(1); - } - } -} - -renameOpenzeppelinDependencies(); diff --git a/pyproject.toml b/pyproject.toml index 7112fb63..881311e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,17 +1,35 @@ [tool.poetry] name = "easy-track" -version = "1.0.0" +version = "1.1.0" description = "" authors = ["Bogdan Kovtun "] license = "GPL-3.0" readme = "README.md" packages = [] +package-mode = false [tool.poetry.dependencies] -python = "3.9.10" -eth-abi = "^2.1.1" -eth-brownie = "^1.18.1" +python = ">=3.10,<3.11" +eth-brownie = "1.20.2" + +[tool.poetry.group.dev.dependencies] +slither-analyzer = "^0.10.2" +python-dateutil = "^2.9.0.post0" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.black] +line-length = 120 +target-version = ['py310'] +include = '\.pyi?$' + +[tool.pytest.ini_options] +testpaths = [ + "tests", +] +filterwarnings = [ + "ignore:abi.(decode|encode):DeprecationWarning", + "ignore:rpc.(snapshot|revert):FutureWarning", +] \ No newline at end of file diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 00000000..b1f3e65f --- /dev/null +++ b/remappings.txt @@ -0,0 +1 @@ +OpenZeppelin/openzeppelin-contracts@4.3.2/=dependencies/OpenZeppelin/openzeppelin-contracts@4.3.2 diff --git a/scripts/acceptance_test_full_setup.py b/scripts/acceptance_test_full_setup.py new file mode 100644 index 00000000..3ff061ab --- /dev/null +++ b/scripts/acceptance_test_full_setup.py @@ -0,0 +1,159 @@ +from brownie import ( + chain, + network, + AllowedRecipientsRegistry, + TopUpAllowedRecipients, + AddAllowedRecipient, + RemoveAllowedRecipient, +) + +from utils import lido, deployed_easy_track, deployed_date_time, log, deployment +from hexbytes import HexBytes + +ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE = "0xec20c52871c824e5437859e75ac830e83aaaaeb7b0ffd850de830ddd3e385276" +REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE = "0x491d7752c25cfca0f73715cde1130022a9b815373f91a996bbb1ba8943efc99b" +SET_PARAMETERS_ROLE = "0x260b83d52a26066d8e9db550fa70395df5f3f064b50ff9d8a94267d9f1fe1967" +UPDATE_SPENT_AMOUNT_ROLE = "0xc5260260446719a726d11a6faece21d19daa48b4cbcca118345832d4cb71df99" +DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000" + +GRANT_ROLE_EVENT = "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d" +REVOKE_ROLE_EVENT = "0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b" + +deploy_config = deployment.AllowedRecipientsFullSetupDeployConfig( + token="", + limit=0, + period=1, + spent_amount=0, + trusted_caller="", + titles=[], + recipients=[], +) + +deployment_tx_hash = "" + + +def main(): + network_name = network.show_active() + + tx = chain.get_transaction(deployment_tx_hash) + + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) + date_time_contract = deployed_date_time.date_time_contract(network=network_name) + + evm_script_executor = et_contracts.evm_script_executor + + registry_address = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + top_up_address = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + add_allowed_recipient_address = tx.events["AddAllowedRecipientDeployed"]["addAllowedRecipient"] + remove_allowed_recipient_address = tx.events["RemoveAllowedRecipientDeployed"]["removeAllowedRecipient"] + + log.br() + + log.nb("Agent", contracts.aragon.agent) + log.nb("Easy Track EVM Script Executor", evm_script_executor) + + log.br() + + log.nb("recipients", deploy_config.recipients) + log.nb("trusted_caller", deploy_config.trusted_caller) + log.nb("limit", deploy_config.limit) + log.nb("period", deploy_config.period) + log.nb("spent_amount", deploy_config.spent_amount) + + log.br() + + log.nb("AllowedRecipientsRegistryDeployed", registry_address) + log.nb("TopUpAllowedRecipientsDeployed", top_up_address) + log.nb("AddAllowedRecipientDeployed", add_allowed_recipient_address) + log.nb("RemoveAllowedRecipientDeployed", remove_allowed_recipient_address) + + log.br() + + registry = AllowedRecipientsRegistry.at(registry_address) + top_up_allowed_recipients = TopUpAllowedRecipients.at(top_up_address) + add_allowed_recipient = AddAllowedRecipient.at(add_allowed_recipient_address) + remove_allowed_recipient = RemoveAllowedRecipient.at(remove_allowed_recipient_address) + + assert registry.bokkyPooBahsDateTimeContract() == date_time_contract + assert top_up_allowed_recipients.easyTrack() == et_contracts.easy_track + assert top_up_allowed_recipients.finance() == contracts.aragon.finance + assert top_up_allowed_recipients.token() == deploy_config.token + assert top_up_allowed_recipients.allowedRecipientsRegistry() == registry + assert top_up_allowed_recipients.trustedCaller() == deploy_config.trusted_caller + assert add_allowed_recipient.allowedRecipientsRegistry() == registry + assert add_allowed_recipient.trustedCaller() == deploy_config.trusted_caller + assert remove_allowed_recipient.allowedRecipientsRegistry() == registry + assert remove_allowed_recipient.trustedCaller() == deploy_config.trusted_caller + + assert len(registry.getAllowedRecipients()) == len(deploy_config.recipients) + for recipient in deploy_config.recipients: + assert registry.isRecipientAllowed(recipient) + + registryLimit, registryPeriodDuration = registry.getLimitParameters() + assert registryLimit == deploy_config.limit + assert registryPeriodDuration == deploy_config.period + + assert registry.spendableBalance() == deploy_config.limit - deploy_config.spent_amount + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, contracts.aragon.agent) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, contracts.aragon.agent) + assert registry.hasRole(SET_PARAMETERS_ROLE, contracts.aragon.agent) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, contracts.aragon.agent) + assert registry.hasRole(DEFAULT_ADMIN_ROLE, contracts.aragon.agent) + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, evm_script_executor) + assert not registry.hasRole(SET_PARAMETERS_ROLE, evm_script_executor) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, evm_script_executor) + + assert not registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(SET_PARAMETERS_ROLE, registry_address) + assert not registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, registry_address) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, registry_address) + + registry_roles_holders = { + ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE: [], + REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE: [], + SET_PARAMETERS_ROLE: [], + UPDATE_SPENT_AMOUNT_ROLE: [], + DEFAULT_ADMIN_ROLE: [], + } + + for event in tx.logs: + # print(event["topics"][0]) + if event["topics"][0] == HexBytes(GRANT_ROLE_EVENT): + registry_roles_holders[event["topics"][1].hex()].append("0x" + event["topics"][2].hex()[26:]) + elif event["topics"][0] == HexBytes(REVOKE_ROLE_EVENT): + registry_roles_holders[event["topics"][1].hex()].remove("0x" + event["topics"][2].hex()[26:]) + + log.br() + + log.nb("Roles holders from tx events") + + log.br() + + log.nb( + "ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE role holders", + registry_roles_holders[ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE], + ) + log.nb( + "REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE role holders", + registry_roles_holders[REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE], + ) + log.nb( + "SET_PARAMETERS_ROLE role holders", + registry_roles_holders[SET_PARAMETERS_ROLE], + ) + log.nb( + "UPDATE_SPENT_AMOUNT_ROLE role holders", + registry_roles_holders[UPDATE_SPENT_AMOUNT_ROLE], + ) + log.nb( + "DEFAULT_ADMIN_ROLE role holders", + registry_roles_holders[DEFAULT_ADMIN_ROLE], + ) + + log.br() diff --git a/scripts/acceptance_test_single_setup.py b/scripts/acceptance_test_single_setup.py new file mode 100644 index 00000000..cd15dc43 --- /dev/null +++ b/scripts/acceptance_test_single_setup.py @@ -0,0 +1,140 @@ +from brownie import chain, network, AllowedRecipientsRegistry, TopUpAllowedRecipients + +from utils import lido, deployed_easy_track, deployed_date_time, log, deployment +from hexbytes import HexBytes + +ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE = "0xec20c52871c824e5437859e75ac830e83aaaaeb7b0ffd850de830ddd3e385276" +REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE = "0x491d7752c25cfca0f73715cde1130022a9b815373f91a996bbb1ba8943efc99b" +SET_PARAMETERS_ROLE = "0x260b83d52a26066d8e9db550fa70395df5f3f064b50ff9d8a94267d9f1fe1967" +UPDATE_SPENT_AMOUNT_ROLE = "0xc5260260446719a726d11a6faece21d19daa48b4cbcca118345832d4cb71df99" +DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000" + +GRANT_ROLE_EVENT = "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d" +REVOKE_ROLE_EVENT = "0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b" + + +deploy_config = deployment.AllowedRecipientsSingleRecipientSetupDeployConfig( + period=0, + spent_amount=0, + title="", + limit=0, + token="", + trusted_caller="", +) + +deployment_tx_hash = "" + + +def main(): + network_name = network.show_active() + + tx = chain.get_transaction(deployment_tx_hash) + + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) + date_time_contract = deployed_date_time.date_time_contract(network=network_name) + + evm_script_executor = et_contracts.evm_script_executor + + registry_address = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + add_allowed_recipient_address = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + log.br() + + log.nb("tx of creation", deployment_tx_hash) + + log.br() + + log.nb("trusted_caller", deploy_config.trusted_caller) + log.nb("token", deploy_config.token) + log.nb("limit", deploy_config.limit) + log.nb("title", deploy_config.title) + log.nb("period", deploy_config.period) + log.nb("spent_amount", deploy_config.spent_amount) + + log.br() + + log.nb("AllowedRecipientsRegistryDeployed", registry_address) + log.nb("TopUpAllowedRecipientsDeployed", add_allowed_recipient_address) + + log.br() + + registry = AllowedRecipientsRegistry.at(registry_address) + top_up_allowed_recipients = TopUpAllowedRecipients.at(add_allowed_recipient_address) + + assert top_up_allowed_recipients.easyTrack() == et_contracts.easy_track + assert top_up_allowed_recipients.finance() == contracts.aragon.finance + assert top_up_allowed_recipients.token() == deploy_config.token + assert top_up_allowed_recipients.allowedRecipientsRegistry() == registry + assert top_up_allowed_recipients.trustedCaller() == deploy_config.trusted_caller + + assert registry.bokkyPooBahsDateTimeContract() == date_time_contract + assert len(registry.getAllowedRecipients()) == 1 + assert registry.isRecipientAllowed(deploy_config.trusted_caller) + + registryLimit, registryPeriodDuration = registry.getLimitParameters() + assert registryLimit == deploy_config.limit + assert registryPeriodDuration == deploy_config.period + + assert registry.spendableBalance() == deploy_config.limit - deploy_config.spent_amount + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, contracts.aragon.agent) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, contracts.aragon.agent) + assert registry.hasRole(SET_PARAMETERS_ROLE, contracts.aragon.agent) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, contracts.aragon.agent) + assert registry.hasRole(DEFAULT_ADMIN_ROLE, contracts.aragon.agent) + + assert not registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, evm_script_executor) + assert not registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, evm_script_executor) + assert not registry.hasRole(SET_PARAMETERS_ROLE, evm_script_executor) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, evm_script_executor) + + assert not registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(SET_PARAMETERS_ROLE, registry_address) + assert not registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, registry_address) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, registry_address) + + registry_roles_holders = { + ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE: [], + REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE: [], + SET_PARAMETERS_ROLE: [], + UPDATE_SPENT_AMOUNT_ROLE: [], + DEFAULT_ADMIN_ROLE: [], + } + + for event in tx.logs: + # print(event["topics"][0]) + if event["topics"][0] == HexBytes(GRANT_ROLE_EVENT): + registry_roles_holders[event["topics"][1].hex()].append("0x" + event["topics"][2].hex()[26:]) + elif event["topics"][0] == HexBytes(REVOKE_ROLE_EVENT): + registry_roles_holders[event["topics"][1].hex()].remove("0x" + event["topics"][2].hex()[26:]) + + log.br() + + log.nb("Roles holders from tx events") + + log.br() + + log.nb( + "ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE role holders", + registry_roles_holders[ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE], + ) + log.nb( + "REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE role holders", + registry_roles_holders[REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE], + ) + log.nb( + "SET_PARAMETERS_ROLE role holders", + registry_roles_holders[SET_PARAMETERS_ROLE], + ) + log.nb( + "UPDATE_SPENT_AMOUNT_ROLE role holders", + registry_roles_holders[UPDATE_SPENT_AMOUNT_ROLE], + ) + log.nb( + "DEFAULT_ADMIN_ROLE role holders", + registry_roles_holders[DEFAULT_ADMIN_ROLE], + ) + + log.br() diff --git a/scripts/compare_bytecode.py b/scripts/compare_bytecode.py new file mode 100644 index 00000000..05279997 --- /dev/null +++ b/scripts/compare_bytecode.py @@ -0,0 +1,50 @@ +from brownie import web3 + +log_color_diff = "\x1b[6;30;42m" +log_color_default = "\x1b[0m" +bytes_per_line = 32 +line_length = bytes_per_line * 2 +format_line_length = max(line_length, 40) + + +def compare(orig_address, comparing_address): + orig_code = web3.eth.get_code(orig_address).hex()[2:] + comparing_code = web3.eth.get_code(comparing_address).hex()[2:] + print(" {0:<{2}} {1:<{2}}\n".format(orig_address, comparing_address, format_line_length)) + + for i in range(max(len(orig_code), len(comparing_code)) // line_length + 1): + code_line = orig_code[i * line_length : (i + 1) * line_length] + comparing_code_line = comparing_code[i * line_length : (i + 1) * line_length] + is_equal = code_line == comparing_code_line + if is_equal: + print( + "{0:>5} {1:<{4}} {2:<4} {3:<{4}}".format(i, code_line, "", comparing_code_line, format_line_length) + ) + else: + color_flag = False + log_code = "" + log_comparing_code = "" + for byte_ind in range(bytes_per_line): + orig_byte = code_line[byte_ind * 2 : (byte_ind + 1) * 2] + comparing_byte = comparing_code_line[byte_ind * 2 : (byte_ind + 1) * 2] + if orig_byte == comparing_byte and color_flag: + color_flag = False + log_code = log_code + log_color_default + log_comparing_code = log_comparing_code + log_color_default + elif orig_byte != comparing_byte and not color_flag: + color_flag = True + log_code = log_code + log_color_diff + log_comparing_code = log_comparing_code + log_color_diff + + log_code = log_code + orig_byte + log_comparing_code = log_comparing_code + comparing_byte + + log_code = log_code + log_color_default + log_comparing_code = log_comparing_code + log_color_default + + print( + "{0:>5} {1:<{4}} {2:<4} {3:<{4}}".format(i, log_code, "neq", log_comparing_code, format_line_length) + ) + print( + f"\n\nBytecode at addresses {orig_address} and {comparing_address} is {'NOT' if orig_code != comparing_code else ''} equal\n\n" + ) diff --git a/scripts/contract_flattener.py b/scripts/contract_flattener.py new file mode 100644 index 00000000..e15cc409 --- /dev/null +++ b/scripts/contract_flattener.py @@ -0,0 +1,73 @@ +import re +import os +from brownie import ( + AllowedRecipientsRegistry, + TopUpAllowedRecipients, + AddAllowedRecipient, + RemoveAllowedRecipient, +) + +IMPORT_PATTERN = re.compile(r"(?<=\n)?import(?P.*)(?P[\"'])(?P.*)(?P=quote)(?P.*)(?=\n)") +PRAGMA_PATTERN = re.compile(r"^pragma.*;$", re.MULTILINE) +LICENSE_PATTERN = re.compile(r"^// SPDX-License-Identifier: (.*)$", re.MULTILINE) + + +def find_dependencies(contract, available_contract_list, sources): + result = [] + current_deps = [x[2] for x in IMPORT_PATTERN.findall(sources[contract]["content"])] + + for contract_dep in current_deps: + inner_results = find_dependencies(contract_dep, available_contract_list, sources) + + for inner_result in inner_results: + result.append(inner_result) + + result.append(contract_dep) + + result.append(contract) + + return result + + +def flatten_contract(container): + contract_name = container.get_verification_info()["contract_name"] + sources = container.get_verification_info()["standard_json_input"]["sources"] + content = [] + + contracts_to_be_included = list(sources.keys()) + + dependencies = find_dependencies(contract_name + ".sol", contracts_to_be_included, sources) + + for dependency in dependencies: + if dependency in contracts_to_be_included: + content.append(sources[dependency]["content"]) + contracts_to_be_included.remove(dependency) + + licenses = set([]) + for i in range(len(content)): + license_search = LICENSE_PATTERN.search(content[i]) + licenses.add(license_search.group(1)) + + licenses_list = list(licenses) + + for i in range(len(content)): + content[i] = IMPORT_PATTERN.sub("", LICENSE_PATTERN.sub("", content[i])) + if i == 0: + continue + + content[i] = PRAGMA_PATTERN.sub("", content[i]) + + content.insert(0, "// SPDX-License-Identifier: " + " & ".join(licenses_list) + "\n") + result = "".join(content) + + filename = "./contracts_flattened/" + contract_name + ".sol" + os.makedirs(os.path.dirname(filename), exist_ok=True) + with open(filename, "w") as f: + f.write(result) + + +def main(): + flatten_contract(AllowedRecipientsRegistry) + flatten_contract(TopUpAllowedRecipients) + flatten_contract(AddAllowedRecipient) + flatten_contract(RemoveAllowedRecipient) diff --git a/scripts/create_full_recipients_setup.py b/scripts/create_full_recipients_setup.py new file mode 100644 index 00000000..a827953a --- /dev/null +++ b/scripts/create_full_recipients_setup.py @@ -0,0 +1,78 @@ +from brownie import chain, network + +from utils.config import ( + get_is_live, + get_deployer_account, + prompt_bool, +) +from utils import ( + log, + lido, + deployment, +) + + +deploy_config = deployment.AllowedRecipientsFullSetupDeployConfig( + token="", + limit=0, + period=1, + spent_amount=0, + trusted_caller="", + titles=[], + recipients=[], +) + + +def main(): + network_name = network.show_active() + deployer = get_deployer_account(get_is_live(), network=network_name) + allowed_recipients_builder = lido.allowed_recipients_builder(network=network_name) + + log.br() + + log.nb("Current network", network_name, color_hl=log.color_magenta) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) + log.ok("chain id", chain.id) + log.ok("Deployer", deployer) + + log.ok("Token", deploy_config.token) + log.ok("Limit", deploy_config.limit) + log.ok("Period", deploy_config.period) + log.ok("Spent amount", deploy_config.spent_amount) + log.ok("Trusted caller", deploy_config.trusted_caller) + log.ok("Titles", deploy_config.titles) + log.ok("Recipients", deploy_config.recipients) + + log.br() + + print("Proceed? [yes/no]: ") + + if not prompt_bool(): + log.nb("Aborting") + return + + tx_params = {"from": deployer, "priority_fee": "2 gwei", "max_fee": "50 gwei"} + + tx = allowed_recipients_builder.deployFullSetup( + deploy_config.trusted_caller, + deploy_config.token, + deploy_config.limit, + deploy_config.period, + deploy_config.recipients, + deploy_config.titles, + deploy_config.spent_amount, + tx_params, + ) + + allowed_recipients_registry_address = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + top_up_allowed_recipients_address = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + add_allowed_recipient_address = tx.events["AddAllowedRecipientDeployed"]["addAllowedRecipient"] + remove_allowed_recipient_address = tx.events["RemoveAllowedRecipientDeployed"]["removeAllowedRecipient"] + + log.ok("Allowed recipients easy track contracts have been deployed...") + log.nb("Deployed AllowedRecipientsRegistry", allowed_recipients_registry_address) + log.nb("Deployed AddAllowedRecipient", add_allowed_recipient_address) + log.nb("Deployed RemoveAllowedRecipient", remove_allowed_recipient_address) + log.nb("Deployed TopUpAllowedRecipients", top_up_allowed_recipients_address) + + log.br() diff --git a/scripts/create_single_recipient_setup.py b/scripts/create_single_recipient_setup.py new file mode 100644 index 00000000..9ce2f07f --- /dev/null +++ b/scripts/create_single_recipient_setup.py @@ -0,0 +1,67 @@ +from brownie import chain, network + +from utils.config import ( + get_is_live, + get_deployer_account, + prompt_bool, +) +from utils import lido, log, deployment + + +deploy_config = deployment.AllowedRecipientsSingleRecipientSetupDeployConfig( + period=0, + spent_amount=0, + title="", + limit=0, + token="", + trusted_caller="", +) + + +def main(): + network_name = network.show_active() + deployer = get_deployer_account(get_is_live(), network=network_name) + allowed_recipients_builder = lido.allowed_recipients_builder(network=network_name) + + log.br() + + log.nb("Current network", network.show_active(), color_hl=log.color_magenta) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) + log.ok("chain id", chain.id) + log.ok("Deployer", deployer) + + log.ok("Token", deploy_config.token) + log.ok("Title", deploy_config.title) + log.ok("Trusted caller", deploy_config.trusted_caller) + log.ok("Limit", deploy_config.limit) + log.ok("Period", deploy_config.period) + log.ok("Spent amount", deploy_config.spent_amount) + + log.br() + + print("Proceed? [yes/no]: ") + + if not prompt_bool(): + log.nb("Aborting") + return + + tx_params = {"from": deployer, "priority_fee": "2 gwei", "max_fee": "50 gwei"} + + tx = allowed_recipients_builder.deploySingleRecipientTopUpOnlySetup( + deploy_config.trusted_caller, + deploy_config.title, + deploy_config.token, + deploy_config.limit, + deploy_config.period, + deploy_config.spent_amount, + tx_params, + ) + + registryAddress = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + topUpAddress = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + + log.ok("Allowed recipients easy track contracts have been deployed...") + log.nb("Deployed AllowedRecipientsRegistryDeployed", registryAddress) + log.nb("Deployed TopUpAllowedRecipientsDeployed", topUpAddress) + + log.br() diff --git a/scripts/deploy.py b/scripts/deploy.py index 79c78396..af14220c 100644 --- a/scripts/deploy.py +++ b/scripts/deploy.py @@ -9,7 +9,7 @@ def main(): - contracts = lido.contracts() + contracts = lido.contracts(network.show_active()) deployer = get_deployer_account(get_is_live()) # address of Lido's LEGO program @@ -44,7 +44,7 @@ def main(): tx_params = { "from": deployer, - "gas_price": "100 gwei" + "gas_price": "100 gwei", # "priority_fee": "4 gwei", } @@ -80,11 +80,9 @@ def deploy_easy_tracks( aragon_calls_script=lido_contracts.aragon.calls_script, tx_params=tx_params, ) - increase_node_operators_staking_limit = ( - deployment.deploy_increase_node_operator_staking_limit( - node_operators_registry=lido_contracts.node_operators_registry, - tx_params=tx_params, - ) + increase_node_operators_staking_limit = deployment.deploy_increase_node_operator_staking_limit( + node_operators_registry=lido_contracts.node_operators_registry, + tx_params=tx_params, ) top_up_lego_program = deployment.deploy_top_up_lego_program( finance=lido_contracts.aragon.finance, diff --git a/scripts/deploy_allowed_recipients_factory.py b/scripts/deploy_allowed_recipients_factory.py new file mode 100644 index 00000000..a9073540 --- /dev/null +++ b/scripts/deploy_allowed_recipients_factory.py @@ -0,0 +1,91 @@ +from brownie import chain, network + +from utils.config import ( + get_env, + get_is_live, + get_deployer_account, + prompt_bool, + get_network_name, +) +from utils import lido, deployed_easy_track, log, deployed_date_time + +from brownie import AllowedRecipientsFactory, AllowedRecipientsBuilder + + +def main(): + network_name = get_network_name() + + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) + deployer = get_deployer_account(get_is_live(), network=network_name) + bokky_poo_bahs_date_time_contract = deployed_date_time.date_time_contract(network=network_name) + + easy_track = et_contracts.easy_track + evm_script_executor = et_contracts.evm_script_executor + + log.br() + + log.nb("Current network", network.show_active(), color_hl=log.color_magenta) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) + log.ok("chain id", chain.id) + log.ok("Deployer", deployer) + log.ok("Governance Token", contracts.ldo) + log.ok("Aragon Finance", contracts.aragon.finance) + log.ok("Aragon Agent", contracts.aragon.agent) + + log.br() + + log.nb("Deployed EasyTrack", easy_track) + log.nb("Deployed EVMScript Executor", evm_script_executor) + + log.br() + + log.nb("BokkyPooBahsDateTimeContract", bokky_poo_bahs_date_time_contract) + + log.br() + + print("Proceed? [yes/no]: ") + + if not prompt_bool(): + log.nb("Aborting") + return + + tx_params = {"from": deployer, "priority_fee": "2 gwei", "max_fee": "50 gwei"} + + (allowed_recipients_factory, allowed_recipients_builder) = deploy_factory_and_builder( + easy_track=easy_track, + finance=contracts.aragon.finance, + agent=contracts.aragon.agent, + bokky_poo_bahs_date_time_contract=bokky_poo_bahs_date_time_contract, + tx_params=tx_params, + ) + + log.br() + + log.ok("Allowed recipients factory and builder have been deployed...") + log.nb("Deployed AllowedRecipientsFactory", allowed_recipients_factory) + log.nb("Deployed AllowedRecipientsBuilder", allowed_recipients_builder) + + log.br() + + if get_is_live() and get_env("FORCE_VERIFY", False): + log.ok("Trying to verify contracts...") + AllowedRecipientsFactory.publish_source(allowed_recipients_factory) + AllowedRecipientsBuilder.publish_source(allowed_recipients_builder) + + +def deploy_factory_and_builder( + easy_track, + finance, + agent, + bokky_poo_bahs_date_time_contract, + tx_params, +): + + factory = AllowedRecipientsFactory.deploy(tx_params) + + builder = AllowedRecipientsBuilder.deploy( + factory, agent, easy_track, finance, bokky_poo_bahs_date_time_contract, tx_params + ) + + return (factory, builder) diff --git a/scripts/deploy_date_time_lib.py b/scripts/deploy_date_time_lib.py new file mode 100644 index 00000000..70f790d6 --- /dev/null +++ b/scripts/deploy_date_time_lib.py @@ -0,0 +1,30 @@ +from brownie import chain, network +from utils.config import ( + get_is_live, + get_deployer_account, + prompt_bool, + get_network_name, +) + +from utils import log + + +def main(): + network_name = get_network_name() + deployer = get_deployer_account(get_is_live(), network=network_name) + + log.br() + log.nb("Current network", network.show_active(), color_hl=log.color_magenta) + log.ok("chain id", chain.id) + log.ok("Deployer", deployer) + + print("Proceed? [yes/no]: ") + + if not prompt_bool(): + log.nb("Aborting") + return + + # The creation bytecode is taken from the deployment tx of the v1 version of the IBokkyPooBahsDateTimeContract https://etherscan.io/tx/0x1ae7118a5a6c25090afc6ef5fe025d008b62d8bda43c4fafa247e566f2ccdbd5 + creation_bytecode = "0x608060405234801561001057600080fd5b506111be806100206000396000f3006080604052600436106102705763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041662501553811461027557806302e98e0d146102a257806310848ddf146102bd578063126702a0146102d557806314b2d6dc146102ea5780631e0582e91461031c5780631f4f77b21461033a57806322f8a2b81461035857806329441674146103705780632af123b8146103855780633293d007146103a05780633e239e1a146103c75780633f9e0eb7146103df5780634355644d146103fa5780634371c46514610415578063442b8c791461042d578063444fda82146104485780634b321502146104635780634df861261461047e5780635e05bd6d1461049357806362fb9697146104ba57806365c72840146104d55780637217523c146104ed57806374f0314f146105085780637be341091461051d57806389a3a00d146105385780638aa001fc146105535780638bbf51b71461056b5780638d4a2d391461058057806390059aed1461059b5780639220d426146105d157806392d66313146106195780639e524caa14610631578063a324ad241461064c578063a3f144ae14610664578063ad203bd414610679578063b05eb08d14610694578063b3bb8cd4146106ac578063b8d16dbc146106c1578063c7b6fd6a146106d9578063c7edf88c146106f4578063c9d3462214610709578063cfbb9f3714610724578063d2b5074314610739578063d6582d0d1461074e578063de5101af14610766578063e95564301461077e578063ea1c169014610793578063f615ed54146107ab578063f9fd5250146107c6578063fa93f883146107db578063ff2258cb146107f3575b600080fd5b34801561028157600080fd5b5061029060043560243561080e565b60408051918252519081900360200190f35b3480156102ae57600080fd5b50610290600435602435610821565b3480156102c957600080fd5b5061029060043561082d565b3480156102e157600080fd5b5061029061083e565b3480156102f657600080fd5b50610308600435602435604435610843565b604080519115158252519081900360200190f35b34801561032857600080fd5b50610290600435602435604435610858565b34801561034657600080fd5b50610290600435602435604435610865565b34801561036457600080fd5b50610290600435610872565b34801561037c57600080fd5b5061029061087d565b34801561039157600080fd5b50610290600435602435610882565b3480156103ac57600080fd5b5061030860043560243560443560643560843560a43561088e565b3480156103d357600080fd5b506102906004356108a9565b3480156103eb57600080fd5b506102906004356024356108b4565b34801561040657600080fd5b506102906004356024356108c0565b34801561042157600080fd5b506103086004356108cc565b34801561043957600080fd5b506102906004356024356108d7565b34801561045457600080fd5b506102906004356024356108e3565b34801561046f57600080fd5b506102906004356024356108ef565b34801561048a57600080fd5b506102906108fb565b34801561049f57600080fd5b5061029060043560243560443560643560843560a435610901565b3480156104c657600080fd5b5061029060043560243561091b565b3480156104e157600080fd5b50610290600435610927565b3480156104f957600080fd5b50610290600435602435610932565b34801561051457600080fd5b5061029061093e565b34801561052957600080fd5b50610290600435602435610945565b34801561054457600080fd5b50610290600435602435610951565b34801561055f57600080fd5b5061029060043561095d565b34801561057757600080fd5b50610290610968565b34801561058c57600080fd5b5061029060043560243561096d565b3480156105a757600080fd5b506105b3600435610979565b60408051938452602084019290925282820152519081900360600190f35b3480156105dd57600080fd5b506105e6610994565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b34801561062557600080fd5b506102906004356109b9565b34801561063d57600080fd5b506102906004356024356109c4565b34801561065857600080fd5b506102906004356109d0565b34801561067057600080fd5b506102906109db565b34801561068557600080fd5b506102906004356024356109e2565b3480156106a057600080fd5b506103086004356109ee565b3480156106b857600080fd5b506102906109f9565b3480156106cd57600080fd5b506103086004356109fd565b3480156106e557600080fd5b50610290600435602435610a08565b34801561070057600080fd5b50610290610a14565b34801561071557600080fd5b50610290600435602435610a19565b34801561073057600080fd5b50610290610a25565b34801561074557600080fd5b50610290610a2a565b34801561075a57600080fd5b50610308600435610a2f565b34801561077257600080fd5b506105b3600435610a3a565b34801561078a57600080fd5b50610290610a55565b34801561079f57600080fd5b506105e6600435610a5a565b3480156107b757600080fd5b50610290600435602435610a80565b3480156107d257600080fd5b50610290610a8c565b3480156107e757600080fd5b50610290600435610a91565b3480156107ff57600080fd5b50610290600435602435610a9c565b600061081a8383610aa8565b9392505050565b600061081a8383610abc565b600061083882610ad9565b92915050565b600281565b6000610850848484610b07565b949350505050565b6000610850848484610b5c565b6000610850848484610bd0565b600061083882610bea565b600781565b600061081a8383610bfd565b600061089e878787878787610c17565b979650505050505050565b600061083882610c57565b600061081a8383610c65565b600061081a8383610ceb565b600061083882610d61565b600061081a8383610d76565b600061081a8383610d9c565b600061081a8383610df7565b610e1081565b600061089e878787878787610e0b565b9695505050505050565b600061081a8383610e35565b600061083882610e49565b600061081a8383610e5a565b6201518081565b600061081a8383610e6f565b600061081a8383610ec3565b600061083882610ed6565b600381565b600061081a8383610edd565b600080600061098784610eed565b9250925092509193909250565b6000806000806000806109a642610f82565b949b939a50919850965094509092509050565b600061083882610fc3565b600061081a8383610fdf565b600061083882610ff2565b62253d8c81565b600061081a838361100d565b60006108388261108e565b4290565b6000610838826110b3565b600061081a83836110d5565b600681565b600061081a83836110ea565b600481565b600581565b600061083882611105565b6000806000610a488461111a565b9196909550909350915050565b603c81565b600080600080600080610a6c87610f82565b949c939b5091995097509550909350915050565b600061081a838361112b565b600181565b60006108388261113b565b600061081a838361114a565b610e10810282038281111561083857600080fd5b600081831115610acb57600080fd5b603c8383035b049392505050565b6000808080610aed62015180865b04610eed565b91945092509050610afe8383610c65565b95945050505050565b6000806107b28510158015610b1c5750600084115b8015610b295750600c8411155b15610b5457610b388585610c65565b9050600083118015610b4a5750808311155b15610b5457600191505b509392505050565b6000808080806107b2881015610b7157600080fd5b50505050600460036064611324600c600d198801819005988901918201929092059290920283900561016f9782029096036001190196909602959095056105b56112c090960195909502059190910192909201036225bad61901919050565b600062015180610be1858585610b5c565b02949350505050565b6007620151809091046003010660010190565b600081831115610c0c57600080fd5b610e10838303610ad1565b6000610c24878787610b07565b1561091157601884108015610c395750603c83105b8015610c455750603c82105b15610911575060019695505050505050565b610e10620151809091060490565b60008160011480610c765750816003145b80610c815750816005145b80610c8c5750816007145b80610c975750816008145b80610ca2575081600a145b80610cad575081600c145b15610cba5750601f610838565b60028214610cca5750601e610838565b610cd38361108e565b610cde57601c610ce1565b601d5b60ff169392505050565b600080808080610cfe6201518088610ae7565b600c91890160001901828104939093019650910660010193509150610d238484610c65565b905080821115610d31578091505b62015180870662015180610d46868686610b5c565b0201945086851015610d5757600080fd5b5050505092915050565b60006006610d6e83610bea565b101592915050565b600080808080610d896201518088610ae7565b918801955093509150610d238484610c65565b600080808080610daf6201518088610ae7565b91889003955093509150610dc38484610c65565b905080821115610dd1578091505b62015180870662015180610de6868686610b5c565b0201945086851115610d5757600080fd5b610e10810282018281101561083857600080fd5b600081603c8402610e10860262015180610e268b8b8b610b5c565b02010101979650505050505050565b600081831115610e4457600080fd5b500390565b600080806109116201518085610ae7565b62015180810282018281101561083857600080fd5b600080808080808087891115610e8457600080fd5b610e91620151808a610ae7565b91975095509350610ea56201518089610ae7565b50600c97880297909102019590950393909303979650505050505050565b603c810282018281101561083857600080fd5b603c900690565b8181018281101561083857600080fd5b60008080836226496581018280808062023ab1600486020593506004600362023ab1860201059094039362164b09610fa0600187010205925060046105b58402058503601f01945061098f85605002811515610f4557fe5b059150605061098f83020585039050600b820560301994909401606402929092018301996002600c90940290910392909201975095509350505050565b6000808080808080610f976201518089610ae7565b919a9099919850610e10620151809092068281049850603c929006828104975091909106945092505050565b60008080610fd46201518085610ae7565b509095945050505050565b603c810282038281111561083857600080fd5b600080806110036201518085610ae7565b5095945050505050565b600080808080806110216201518089610ae7565b91965094509250600c808602850188900360001901925082049450600c8206600101935061104f8585610c65565b90508083111561105d578092505b62015180880662015180611072878787610b5c565b020195508786111561108357600080fd5b505050505092915050565b6000600482061580156110a357506064820615155b8061083857505061019090061590565b60008080806110c56201518086610ae7565b91945092509050610afe8361108e565b62015180810282038281111561083857600080fd5b6000818311156110f957600080fd5b62015180838303610ad1565b6000600561111283610bea565b111592915050565b60008080610a486201518085610ae7565b8082038281111561083857600080fd5b6000610e108206603c81610ad1565b60008080808080808789111561115f57600080fd5b61116c620151808a610ae7565b919750955093506111806201518089610ae7565b505095909503989750505050505050505600a165627a7a7230582093939dd9a1018aabebf4ab93ad48e1e2f314aa395c430e73b58496aa461992e10029" + + deployer.transfer(data=creation_bytecode, priority_fee="2 gwei", max_fee="50 gwei") diff --git a/scripts/deploy_limit_enabled_payout_factories.py b/scripts/deploy_limit_enabled_payout_factories.py new file mode 100644 index 00000000..7c7e6414 --- /dev/null +++ b/scripts/deploy_limit_enabled_payout_factories.py @@ -0,0 +1,146 @@ +from brownie import chain, network + +from utils.config import ( + get_env, + get_is_live, + get_deployer_account, + prompt_bool, + get_network_name, +) +from utils import deployment, lido, deployed_easy_track, deployed_date_time, log + +from brownie import ( + AllowedRecipientsRegistry, + AddAllowedRecipient, + RemoveAllowedRecipient, + TopUpAllowedRecipients, +) + + +def main(): + network_name = get_network_name() + + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) + deployer = get_deployer_account(get_is_live(), network=network_name) + date_time_contract = deployed_date_time.date_time_contract(network=network_name) + + easy_track = et_contracts.easy_track + evm_script_executor = et_contracts.evm_script_executor + + # address allowed to create motions to add, remove or top up allowed recipients + committee_multisig = get_env("COMMITTEE_MULTISIG") + + log.br() + + log.nb("Current network", network.show_active(), color_hl=log.color_magenta) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) + log.ok("chain id", chain.id) + log.ok("Deployer", deployer) + log.ok("Governance Token", contracts.ldo) + log.ok("Aragon Voting", contracts.aragon.voting) + log.ok("Aragon Finance", contracts.aragon.finance) + + log.br() + + log.nb("Committee Multisig", committee_multisig) + log.nb("Deployed BokkyPooBahsDateTimeContract", date_time_contract) + log.nb("Deployed EasyTrack", easy_track) + log.nb("Deployed EVMScript Executor", evm_script_executor) + + log.br() + + print("Proceed? [yes/no]: ") + + if not prompt_bool(): + log.nb("Aborting") + return + + tx_params = {"from": deployer} + if get_is_live(): + tx_params["priority_fee"] = "2 gwei" + tx_params["max_fee"] = "300 gwei" + + ( + allowed_recipients_registry, + add_allowed_recipient, + remove_allowed_recipient, + top_up_allowed_recipients, + ) = deploy_allowed_recipients_contracts( + evm_script_executor=evm_script_executor, + lido_contracts=contracts, + committee_multisig=committee_multisig, + easy_track=easy_track, + date_time_contract=date_time_contract, + tx_params=tx_params, + ) + + log.br() + + log.ok("Allowed recipients factories have been deployed...") + log.nb("Deployed AllowedRecipientsRegistry", allowed_recipients_registry) + log.nb("Deployed AddAllowedRecipient", add_allowed_recipient) + log.nb("Deployed RemoveAllowedRecipient", remove_allowed_recipient) + log.nb("Deployed TopUpAllowedRecipients", top_up_allowed_recipients) + + log.br() + + if get_is_live() and get_env("FORCE_VERIFY", False): + log.ok("Trying to verify contracts...") + AllowedRecipientsRegistry.publish_source(allowed_recipients_registry) + AddAllowedRecipient.publish_source(add_allowed_recipient) + RemoveAllowedRecipient.publish_source(remove_allowed_recipient) + TopUpAllowedRecipients.publish_source(top_up_allowed_recipients) + + log.br() + + if easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), contracts.aragon.voting): + log.ok("Easy Track is under DAO Voting control") + log.ok("To finalize deploy, please create voting that adds factories to Easy Track") + else: + log.ok("Easy Track is under another account's control") + log.ok("To finalize deploy, please manually add factories to Easy Track") + + print("Hit to quit script") + input() + + +def deploy_allowed_recipients_contracts( + evm_script_executor, + lido_contracts, + committee_multisig, + easy_track, + date_time_contract, + tx_params, +): + allowed_recipients_registry = deployment.deploy_allowed_recipients_registry( + voting=lido_contracts.aragon.voting, + evm_script_executor=evm_script_executor, + date_time_contract=date_time_contract, + tx_params=tx_params, + ) + add_allowed_recipient = deployment.deploy_add_allowed_recipient( + allowed_recipients_registry=allowed_recipients_registry, + committee_multisig=committee_multisig, + tx_params=tx_params, + ) + remove_allowed_recipient = deployment.deploy_remove_allowed_recipient( + allowed_recipients_registry=allowed_recipients_registry, + committee_multisig=committee_multisig, + tx_params=tx_params, + ) + top_up_allowed_recipients = deployment.deploy_top_up_allowed_recipients( + finance=lido_contracts.aragon.finance, + governance_token=lido_contracts.ldo, + allowed_recipients_registry=allowed_recipients_registry, + committee_multisig=committee_multisig, + easy_track=easy_track, + tx_params=tx_params, + ) + + return ( + allowed_recipients_registry, + add_allowed_recipient, + remove_allowed_recipient, + top_up_allowed_recipients, + ) diff --git a/scripts/deploy_reward_programs.py b/scripts/deploy_reward_programs.py index 97cc30a1..8546543d 100644 --- a/scripts/deploy_reward_programs.py +++ b/scripts/deploy_reward_programs.py @@ -5,28 +5,19 @@ get_is_live, get_deployer_account, prompt_bool, - network_name -) -from utils import ( - deployment, - lido, - deployed_easy_track, - log + get_network_name, ) +from utils import deployment, lido, deployed_easy_track, log + +from brownie import RewardProgramsRegistry, AddRewardProgram, RemoveRewardProgram, TopUpRewardPrograms -from brownie import ( - RewardProgramsRegistry, - AddRewardProgram, - RemoveRewardProgram, - TopUpRewardPrograms -) def main(): - netname = "goerli" if network_name().split('-')[0] == "goerli" else "mainnet" + network_name = get_network_name() - contracts = lido.contracts(network=netname) - et_contracts = deployed_easy_track.contracts(network=netname) - deployer = get_deployer_account(get_is_live(), network=netname) + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) + deployer = get_deployer_account(get_is_live(), network=network_name) easy_track = et_contracts.easy_track evm_script_executor = et_contracts.evm_script_executor @@ -37,7 +28,7 @@ def main(): log.br() log.nb("Current network", network.show_active(), color_hl=log.color_magenta) - log.nb("Using deployed addresses for", netname, color_hl=log.color_yellow) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) log.ok("chain id", chain.id) log.ok("Deployer", deployer) log.ok("Governance Token", contracts.ldo) @@ -58,21 +49,18 @@ def main(): log.nb("Aborting") return - tx_params = { "from": deployer } - if (get_is_live()): + tx_params = {"from": deployer} + if get_is_live(): tx_params["priority_fee"] = "2 gwei" tx_params["max_fee"] = "300 gwei" - ( - reward_programs_registry, - add_reward_program, - remove_reward_program, - top_up_reward_programs - ) = deploy_reward_programs_contracts( - evm_script_executor=evm_script_executor, - lido_contracts=contracts, - reward_programs_multisig=reward_programs_multisig, - tx_params=tx_params, + (reward_programs_registry, add_reward_program, remove_reward_program, top_up_reward_programs) = ( + deploy_reward_programs_contracts( + evm_script_executor=evm_script_executor, + lido_contracts=contracts, + reward_programs_multisig=reward_programs_multisig, + tx_params=tx_params, + ) ) log.br() @@ -85,7 +73,7 @@ def main(): log.br() - if (get_is_live() and get_env("FORCE_VERIFY", False)): + if get_is_live() and get_env("FORCE_VERIFY", False): log.ok("Trying to verify contracts...") RewardProgramsRegistry.publish_source(reward_programs_registry) AddRewardProgram.publish_source(add_reward_program) @@ -108,7 +96,7 @@ def main(): remove_reward_program=remove_reward_program, top_up_reward_programs=top_up_reward_programs, reward_programs_registry=reward_programs_registry, - lido_contracts=contracts + lido_contracts=contracts, ) elif easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), contracts.aragon.voting): log.ok("Easy Track is under DAO Voting control") @@ -150,9 +138,4 @@ def deploy_reward_programs_contracts( tx_params=tx_params, ) - return ( - reward_programs_registry, - add_reward_program, - remove_reward_program, - top_up_reward_programs - ) + return (reward_programs_registry, add_reward_program, remove_reward_program, top_up_reward_programs) diff --git a/scripts/deploy_simple_dvt_factories.py b/scripts/deploy_simple_dvt_factories.py new file mode 100644 index 00000000..7e52a720 --- /dev/null +++ b/scripts/deploy_simple_dvt_factories.py @@ -0,0 +1,188 @@ +import json +import os + +from brownie import ( + chain, + AddNodeOperators, + ActivateNodeOperators, + DeactivateNodeOperators, + ChangeNodeOperatorManagers, + SetNodeOperatorNames, + SetNodeOperatorRewardAddresses, + SetVettedValidatorsLimits, + UpdateTargetValidatorLimits, + IncreaseVettedValidatorsLimit, + web3, +) + +from utils import lido, log +from utils.config import ( + get_is_live, + get_deployer_account, + prompt_bool, + get_network_name, +) + + +def get_trusted_caller(): + if "TRUSTED_CALLER" not in os.environ: + raise EnvironmentError("Please set TRUSTED_CALLER env variable") + trusted_caller = os.environ["TRUSTED_CALLER"] + + assert web3.isAddress(trusted_caller), "Trusted caller address is not valid" + + return trusted_caller + + +def main(): + network_name = get_network_name() + contracts = lido.contracts(network=network_name) + + deployer = get_deployer_account(get_is_live(), network=network_name) + trusted_caller = get_trusted_caller() + simple_dvt = contracts.simple_dvt.address + acl = contracts.aragon.acl.address + lido_address = contracts.steth.address + + log.br() + + log.nb("Current network", network_name, color_hl=log.color_magenta) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) + log.nb("chain id", chain.id) + + log.br() + + log.ok("Deployer", deployer) + + log.br() + + log.ok("Simple DVT module address", simple_dvt) + log.ok("ACL", acl) + log.ok("Trusted caller", trusted_caller) + log.ok("Lido", lido_address) + + log.br() + + print("Proceed? [yes/no]: ") + + if not prompt_bool(): + log.nb("Aborting") + return + + tx_params = {"from": deployer, "priority_fee": "2 gwei", "max_fee": "50 gwei"} + + log.br() + + deployment_artifacts = {} + + # AddNodeOperators + add_node_operator = AddNodeOperators.deploy(trusted_caller, simple_dvt, acl, lido_address, tx_params) + deployment_artifacts["AddNodeOperators"] = { + "contract": "AddNodeOperators", + "address": add_node_operator.address, + "constructorArgs": [trusted_caller, simple_dvt, acl, lido_address], + } + + # ActivateNodeOperators + activate_node_operators = ActivateNodeOperators.deploy(trusted_caller, simple_dvt, acl, tx_params) + deployment_artifacts["ActivateNodeOperators"] = { + "contract": "ActivateNodeOperators", + "address": activate_node_operators.address, + "constructorArgs": [trusted_caller, simple_dvt, acl], + } + + # DeactivateNodeOperators + deactivate_node_operators = DeactivateNodeOperators.deploy(trusted_caller, simple_dvt, acl, tx_params) + deployment_artifacts["DeactivateNodeOperators"] = { + "contract": "DeactivateNodeOperators", + "address": deactivate_node_operators.address, + "constructorArgs": [trusted_caller, simple_dvt, acl], + } + + # SetVettedValidatorsLimits + set_vetted_validators_limits = SetVettedValidatorsLimits.deploy(trusted_caller, simple_dvt, tx_params) + deployment_artifacts["SetVettedValidatorsLimits"] = { + "contract": "SetVettedValidatorsLimits", + "address": set_vetted_validators_limits.address, + "constructorArgs": [trusted_caller, simple_dvt], + } + + # IncreaseVettedValidatorsLimit + increase_vetted_validators_limits = IncreaseVettedValidatorsLimit.deploy(simple_dvt, tx_params) + deployment_artifacts["IncreaseVettedValidatorsLimit"] = { + "contract": "IncreaseVettedValidatorsLimit", + "address": increase_vetted_validators_limits.address, + "constructorArgs": [trusted_caller, simple_dvt], + } + + # SetNodeOperatorNames + set_node_operator_names = SetNodeOperatorNames.deploy(trusted_caller, simple_dvt, tx_params) + deployment_artifacts["SetNodeOperatorNames"] = { + "contract": "SetNodeOperatorNames", + "address": set_node_operator_names.address, + "constructorArgs": [trusted_caller, simple_dvt], + } + + # SetNodeOperatorRewardAddresses + set_node_operator_reward = SetNodeOperatorRewardAddresses.deploy( + trusted_caller, simple_dvt, lido_address, tx_params + ) + deployment_artifacts["SetNodeOperatorRewardAddresses"] = { + "contract": "SetNodeOperatorRewardAddresses", + "address": set_node_operator_reward.address, + "constructorArgs": [trusted_caller, simple_dvt, lido_address], + } + + # UpdateTargetValidatorLimits + update_tareget_validator_limits = UpdateTargetValidatorLimits.deploy(trusted_caller, simple_dvt, tx_params) + deployment_artifacts["UpdateTargetValidatorLimits"] = { + "contract": "UpdateTargetValidatorLimits", + "address": update_tareget_validator_limits.address, + "constructorArgs": [trusted_caller, simple_dvt], + } + + # ChangeNodeOperatorManagers + change_node_operator_manager = ChangeNodeOperatorManagers.deploy(trusted_caller, simple_dvt, acl, tx_params) + deployment_artifacts["ChangeNodeOperatorManagers"] = { + "contract": "ChangeNodeOperatorManagers", + "address": change_node_operator_manager.address, + "constructorArgs": [trusted_caller, simple_dvt, acl], + } + + log.ok("Deployed AddNodeOperators", add_node_operator) + log.ok("Deployed ActivateNodeOperators", activate_node_operators.address) + log.ok("Deployed DeactivateNodeOperators", deactivate_node_operators.address) + log.ok("Deployed SetVettedValidatorsLimits", set_vetted_validators_limits.address) + log.ok( + "Deployed IncreaseVettedValidatorsLimit", + increase_vetted_validators_limits.address, + ) + log.ok("Deployed SetNodeOperatorNames", set_node_operator_names.address) + log.ok( + "Deployed SetNodeOperatorRewardAddresses", + set_node_operator_reward.address, + ) + log.ok("Deployed UpdateTargetValidatorLimits", update_tareget_validator_limits.address) + log.ok("Deployed ChangeNodeOperatorManagers", change_node_operator_manager.address) + + log.br() + log.nb("All factories have been deployed.") + log.nb("Saving atrifacts...") + + with open(f"deployed-{network_name}.json", "w") as outfile: + json.dump(deployment_artifacts, outfile) + + log.nb("Starting code verification.") + log.br() + + AddNodeOperators.publish_source(add_node_operator) + ActivateNodeOperators.publish_source(activate_node_operators) + DeactivateNodeOperators.publish_source(deactivate_node_operators) + SetVettedValidatorsLimits.publish_source(set_vetted_validators_limits) + IncreaseVettedValidatorsLimit.publish_source(increase_vetted_validators_limits) + SetNodeOperatorNames.publish_source(set_node_operator_names) + SetNodeOperatorRewardAddresses.publish_source(set_node_operator_reward) + UpdateTargetValidatorLimits.publish_source(update_tareget_validator_limits) + ChangeNodeOperatorManagers.publish_source(change_node_operator_manager) + + log.br() diff --git a/scripts/final_check.py b/scripts/final_check.py index 103a2518..3500cd06 100644 --- a/scripts/final_check.py +++ b/scripts/final_check.py @@ -16,16 +16,14 @@ ZERO_ADDRESS, ) from utils import lido, constants, log, mainnet_fork, evm_script -from eth_abi import encode_single from scripts.grant_executor_permissions import grant_executor_permissions from brownie.network.account import PublicKeyAccount +from utils.evm_script import encode_calldata def main(): grant_permissions_voting_id = ( - os.environ["GRANT_PERMISSIONS_VOTING_ID"] - if "GRANT_PERMISSIONS_VOTING_ID" in os.environ - else None + os.environ["GRANT_PERMISSIONS_VOTING_ID"] if "GRANT_PERMISSIONS_VOTING_ID" in os.environ else None ) deployer = "0x2a61d3ba5030Ef471C74f612962c7367ECa3a62d" lego_committee_multisig = "0x12a43b049A7D330cB8aEAB5113032D18AE9a9030" @@ -35,27 +33,15 @@ def main(): lido_contracts = lido.contracts(network="mainnet") easy_track = EasyTrack.at("0xF0211b7660680B49De1A7E9f25C65660F0a13Fea") - evm_script_executor = EVMScriptExecutor.at( - "0xFE5986E06210aC1eCC1aDCafc0cc7f8D63B3F977" - ) + evm_script_executor = EVMScriptExecutor.at("0xFE5986E06210aC1eCC1aDCafc0cc7f8D63B3F977") increase_node_operators_staking_limit = IncreaseNodeOperatorStakingLimit.at( "0xFeBd8FAC16De88206d4b18764e826AF38546AfE0" ) - top_up_lego_program = TopUpLegoProgram.at( - "0x648C8Be548F43eca4e482C0801Ebccccfb944931" - ) - reward_programs_registry = RewardProgramsRegistry.at( - "0x3129c041b372ee93a5a8756dc4ec6f154d85bc9a" - ) - add_reward_program = AddRewardProgram.at( - "0x9D15032b91d01d5c1D940eb919461426AB0dD4e3" - ) - remove_reward_program = RemoveRewardProgram.at( - "0xc21e5e72Ffc223f02fC410aAedE3084a63963932" - ) - top_up_reward_programs = TopUpRewardPrograms.at( - "0x77781A93C4824d2299a38AC8bBB11eb3cd6Bc3B7" - ) + top_up_lego_program = TopUpLegoProgram.at("0x648C8Be548F43eca4e482C0801Ebccccfb944931") + reward_programs_registry = RewardProgramsRegistry.at("0x3129c041b372ee93a5a8756dc4ec6f154d85bc9a") + add_reward_program = AddRewardProgram.at("0x9D15032b91d01d5c1D940eb919461426AB0dD4e3") + remove_reward_program = RemoveRewardProgram.at("0xc21e5e72Ffc223f02fC410aAedE3084a63963932") + top_up_reward_programs = TopUpRewardPrograms.at("0x77781A93C4824d2299a38AC8bBB11eb3cd6Bc3B7") log.ok("LEGO Program Multisig", lego_committee_multisig) log.ok("Reward Programs Multisig", reward_programs_multisig) @@ -169,17 +155,11 @@ def main(): ) -def validate_easy_track_setup( - easy_track, evm_script_executor, lido_contracts, pause_address, deployer -): +def validate_easy_track_setup(easy_track, evm_script_executor, lido_contracts, pause_address, deployer): voting = lido_contracts.aragon.voting log.nb("EasyTrack", easy_track) - assert_equals( - " governanceToken:", easy_track.governanceToken(), lido_contracts.ldo - ) - assert_equals( - " evmScriptExecutor", easy_track.evmScriptExecutor(), evm_script_executor - ) + assert_equals(" governanceToken:", easy_track.governanceToken(), lido_contracts.ldo) + assert_equals(" evmScriptExecutor", easy_track.evmScriptExecutor(), evm_script_executor) assert_equals( " motionDuration", easy_track.motionDuration(), @@ -260,9 +240,7 @@ def validate_evm_script_executor_setup(evm_script_executor, easy_track, lido_con print() -def validate_increase_node_operator_staking_limit_setup( - increase_node_operators_staking_limit, lido_contracts -): +def validate_increase_node_operator_staking_limit_setup(increase_node_operators_staking_limit, lido_contracts): log.nb("IncreaseNodeOperatorsStakingLimit", increase_node_operators_staking_limit) assert_equals( " nodeOperatorsRegistry:", @@ -272,16 +250,10 @@ def validate_increase_node_operator_staking_limit_setup( print() -def validate_top_up_lego_program_setup( - top_up_lego_program, lido_contracts, lego_committee_multisig -): +def validate_top_up_lego_program_setup(top_up_lego_program, lido_contracts, lego_committee_multisig): log.nb("TopUpLegoProgram", top_up_lego_program) - assert_equals( - " finance", top_up_lego_program.finance(), lido_contracts.aragon.finance - ) - assert_equals( - " legoProgram", top_up_lego_program.legoProgram(), lego_committee_multisig - ) + assert_equals(" finance", top_up_lego_program.finance(), lido_contracts.aragon.finance) + assert_equals(" legoProgram", top_up_lego_program.legoProgram(), lego_committee_multisig) assert_equals( " trustedCaller", top_up_lego_program.trustedCaller(), @@ -290,51 +262,37 @@ def validate_top_up_lego_program_setup( print() -def validate_reward_programs_registry_setup( - reward_programs_registry, deployer, evm_script_executor, lido_contracts -): +def validate_reward_programs_registry_setup(reward_programs_registry, deployer, evm_script_executor, lido_contracts): voting = lido_contracts.aragon.voting log.nb("RewardProgramsRegistry", reward_programs_registry) assert_equals( f" voting ({voting}) has DEFAULT_ADMIN_ROLE", - reward_programs_registry.hasRole( - reward_programs_registry.DEFAULT_ADMIN_ROLE(), voting - ), + reward_programs_registry.hasRole(reward_programs_registry.DEFAULT_ADMIN_ROLE(), voting), True, ) assert_equals( f" deployer ({deployer}) has no DEFAULT_ADMIN role", - not reward_programs_registry.hasRole( - reward_programs_registry.DEFAULT_ADMIN_ROLE(), deployer - ), + not reward_programs_registry.hasRole(reward_programs_registry.DEFAULT_ADMIN_ROLE(), deployer), True, ) assert_equals( f" deployer ({deployer}) has no ADD_REWARD_PROGRAM_ROLE role", - not reward_programs_registry.hasRole( - reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), deployer - ), + not reward_programs_registry.hasRole(reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), deployer), True, ) assert_equals( f" deployer ({deployer}) has no REMOVE_REWARD_PROGRAM_ROLE role", - not reward_programs_registry.hasRole( - reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), deployer - ), + not reward_programs_registry.hasRole(reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), deployer), True, ) assert_equals( f" voting ({voting}) has ADD_REWARD_PROGRAM_ROLE", - reward_programs_registry.hasRole( - reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), voting - ), + reward_programs_registry.hasRole(reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), voting), True, ) assert_equals( f" voting ({voting}) has REMOVE_REWARD_PROGRAM_ROLE", - reward_programs_registry.hasRole( - reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), voting - ), + reward_programs_registry.hasRole(reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), voting), True, ) assert_equals( @@ -356,9 +314,7 @@ def validate_reward_programs_registry_setup( print() -def validate_add_reward_program_setup( - add_reward_program, reward_programs_multisig, reward_programs_registry -): +def validate_add_reward_program_setup(add_reward_program, reward_programs_multisig, reward_programs_registry): log.nb("AddRewardProgram", add_reward_program) assert_equals( " trustedCaller", @@ -373,9 +329,7 @@ def validate_add_reward_program_setup( print() -def validate_remove_reward_program( - remove_reward_program, reward_programs_multisig, reward_programs_registry -): +def validate_remove_reward_program(remove_reward_program, reward_programs_multisig, reward_programs_registry): log.nb("RemoveRewardProgram", remove_reward_program) assert_equals( " trustedCaller", @@ -402,12 +356,8 @@ def validate_top_up_reward_programs( top_up_reward_programs.trustedCaller(), reward_programs_multisig, ) - assert_equals( - " finance", top_up_reward_programs.finance(), lido_contracts.aragon.finance - ) - assert_equals( - " rewardToken", top_up_reward_programs.rewardToken(), lido_contracts.ldo - ) + assert_equals(" finance", top_up_reward_programs.finance(), lido_contracts.aragon.finance) + assert_equals(" rewardToken", top_up_reward_programs.rewardToken(), lido_contracts.ldo) assert_equals( " rewardProgramsRegistry", top_up_reward_programs.rewardProgramsRegistry(), @@ -416,10 +366,9 @@ def validate_top_up_reward_programs( def grant_aragon_permissions(lido_contracts, evm_script_executor, voting_id=None): - lido_permissions = lido.permissions(contracts=lido_contracts) permissions_to_grant = [ - lido_permissions.finance.CREATE_PAYMENTS_ROLE, - lido_permissions.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE, + lido_contracts.permissions.finance.CREATE_PAYMENTS_ROLE, + lido_contracts.permissions.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE, ] log.nb("") log.nb( @@ -436,7 +385,7 @@ def grant_aragon_permissions(lido_contracts, evm_script_executor, voting_id=None log.ok(" Voting was started. Voting id", voting_id) else: log.ok(f" Voting {voting_id} was started separately.") - lido.execute_voting(voting_id=voting_id) + lido_contracts.execute_voting(voting_id) log.ok(f" Voting {voting_id} successfully passed") assert_equals( " EVMScriptExecutor has role CREATE_PAYMENTS_ROLE", @@ -471,7 +420,7 @@ def simulate_reward_program_addition( log.nb("Simulate reward program addition via EasyTrack") log.nb("") add_reward_program_calldata = encode_calldata( - "(address,string)", [reward_program_address, "Mock Reward Program"] + ["address", "string"], [reward_program_address, "Mock Reward Program"] ) log.ok(" Address of new reward program", reward_program_address) tx, motion = create_motion( @@ -480,9 +429,7 @@ def simulate_reward_program_addition( calldata=add_reward_program_calldata, creator=reward_programs_multisig, ) - expected_evm_script = add_reward_program.createEVMScript( - reward_programs_multisig, add_reward_program_calldata - ) + expected_evm_script = add_reward_program.createEVMScript(reward_programs_multisig, add_reward_program_calldata) assert_motion_created_event( tx=tx, creator=reward_programs_multisig, @@ -524,9 +471,9 @@ def simulate_reward_program_top_up( log.nb("") log.nb("Simulate reward program top up via EasyTrack") log.nb("") - top_up_amount = Wei(200_000 * 10 ** 18) + top_up_amount = Wei(200_000 * 10**18) top_up_reward_program_calldata = encode_calldata( - "(address[],uint256[])", + ["address[]", "uint256[]"], [[reward_program_address], [top_up_amount]], ) log.ok(" Address of reward program to top up", reward_program_address) @@ -586,9 +533,7 @@ def simulate_reward_program_removing( log.nb("") log.nb("Simulate reward program removing via EasyTrack") log.nb("") - remove_reward_program_calldata = encode_calldata( - "(address)", [reward_program_address] - ) + remove_reward_program_calldata = encode_calldata(["address"], [reward_program_address]) log.ok(" Address of reward program to remove", reward_program_address) assert_equals( " Reward program listed in reward programs registry", @@ -649,10 +594,8 @@ def simulate_lego_program_top_up( lido_contracts.ldo.address, lido_contracts.steth.address, ] - reward_amounts = [Wei(100 * 10 ** 18), Wei(200_000 * 10 ** 18), Wei(50 * 10 ** 18)] - top_up_lego_program_calldata = encode_calldata( - "(address[],uint256[])", [reward_tokens, reward_amounts] - ) + reward_amounts = [Wei(100 * 10**18), Wei(200_000 * 10**18), Wei(50 * 10**18)] + top_up_lego_program_calldata = encode_calldata(["address[]", "uint256[]"], [reward_tokens, reward_amounts]) log.ok(" Address of LEGO program", lego_committee_multisig) log.ok(" Tokens to transfer", reward_tokens) log.ok(" Amount of tokens to transfer", reward_amounts) @@ -669,9 +612,7 @@ def simulate_lego_program_top_up( calldata=top_up_lego_program_calldata, creator=lego_committee_multisig, ) - expected_evm_script = top_up_lego_program.createEVMScript( - lego_committee_multisig, top_up_lego_program_calldata - ) + expected_evm_script = top_up_lego_program.createEVMScript(lego_committee_multisig, top_up_lego_program_calldata) assert_motion_created_event( tx=tx, creator=lego_committee_multisig, @@ -732,9 +673,7 @@ def simulate_node_operator_increases_staking_limit( log.ok("Node operator total signing keys", total_signing_keys) log.ok("New node operator staking limit to set", total_signing_keys) - increase_staking_limit_calldata = encode_calldata( - "(uint256,uint256)", [node_operator_id, total_signing_keys] - ) + increase_staking_limit_calldata = encode_calldata(["uint256", "uint256"], [node_operator_id, total_signing_keys]) tx, motion = create_motion( easy_track=easy_track, evm_script_factory=increase_node_operator_staking_limit, @@ -766,9 +705,7 @@ def simulate_node_operator_increases_staking_limit( motion_id=motion[0], motion_calldata=increase_staking_limit_calldata, ) - node_operator = lido_contracts.node_operators_registry.getNodeOperator( - node_operator_id, True - ) + node_operator = lido_contracts.node_operators_registry.getNodeOperator(node_operator_id, True) assert_equals(" New node operator staking limit after", node_operator[3], 3) print() @@ -788,16 +725,14 @@ def simulate_unpause_by_voting(easy_track, pause_multisig, lido_contracts): log.nb("Simulate unpausing via Aragon voting") log.nb("") assert_equals(" EasyTrack is still paused", easy_track.paused(), True) - unpause_evm_scirpt = evm_script.encode_call_script( - [(easy_track.address, easy_track.unpause.encode_input())] - ) + unpause_evm_scirpt = evm_script.encode_call_script([(easy_track.address, easy_track.unpause.encode_input())]) voting_id, _ = lido.create_voting( - unpause_evm_scirpt, - "Unpause EasyTracks", - {"from": lido_contracts.aragon.agent}, + evm_script=unpause_evm_scirpt, + description="Unpause EasyTracks", + tx_params={"from": lido_contracts.aragon.agent}, ) log.ok(" Voting was started. Voting id", voting_id) - lido.execute_voting(voting_id) + lido_contracts.execute_voting(voting_id) log.ok(" Voting was executed") assert_equals(" EasyTrack is paused", easy_track.paused(), False) print() @@ -819,19 +754,17 @@ def add_new_node_operator(lido_contracts): [(node_operators_registry.address, add_node_operator_calldata)] ) voting_id, _ = lido.create_voting( - add_node_operator_evm_script, - "Add node operator to registry", - {"from": lido_contracts.aragon.agent}, + evm_script=add_node_operator_evm_script, + description="Add node operator to registry", + tx_params={"from": lido_contracts.aragon.agent}, ) log.ok(" Voting was started. Voting id", voting_id) # execute vote to add test node operator - lido.execute_voting(voting_id) + lido_contracts.execute_voting(voting_id) # validate new node operator id new_node_operator_id = node_operators_registry.getActiveNodeOperatorsCount() - 1 - new_node_operator = node_operators_registry.getNodeOperator( - new_node_operator_id, True - ) + new_node_operator = node_operators_registry.getNodeOperator(new_node_operator_id, True) assert new_node_operator[0] # active assert new_node_operator[1] == node_operator["name"] # name assert new_node_operator[2] == node_operator["address"] # rewardAddress @@ -860,9 +793,7 @@ def add_new_node_operator(lido_contracts): ) # validate that signing keys have been added - new_node_operator = node_operators_registry.getNodeOperator( - new_node_operator_id, True - ) + new_node_operator = node_operators_registry.getNodeOperator(new_node_operator_id, True) assert new_node_operator[5] == len(signing_keys["pubkeys"]) # totalSigningKeys assert new_node_operator[6] == 0 # usedSigningKeys return ( @@ -884,13 +815,9 @@ def wait_before_enact(motion): ) -def assert_motion_created_event( - tx, creator, evm_script_factory, evm_script_calldata, evm_script -): +def assert_motion_created_event(tx, creator, evm_script_factory, evm_script_calldata, evm_script): assert_equals(" MotionCreated Event Fired", "MotionCreated" in tx.events, True) - assert_equals( - " MotionCreated._creator", tx.events["MotionCreated"]["_creator"], creator - ) + assert_equals(" MotionCreated._creator", tx.events["MotionCreated"]["_creator"], creator) assert_equals( " MotionCreated._evmScriptFactory", tx.events["MotionCreated"]["_evmScriptFactory"], @@ -950,9 +877,7 @@ def create_motion(easy_track, evm_script_factory, calldata, creator): log.ok(" Sending createMotion transaction...") tx = easy_track.createMotion(evm_script_factory, calldata, {"from": creator}) motions = easy_track.getMotions() - assert_equals( - " New motion was created", len(motions) == count_of_motions_before + 1, True - ) + assert_equals(" New motion was created", len(motions) == count_of_motions_before + 1, True) return tx, motions[0] @@ -960,7 +885,3 @@ def enact_motion(easy_track, motion_id, motion_calldata): log.ok(" Sending enactMotion transaction...") easy_track.enactMotion(motion_id, motion_calldata, {"from": accounts[2]}) assert_equals(" Motion was enacted", len(easy_track.getMotions()) == 0, True) - - -def encode_calldata(signature, values): - return "0x" + encode_single(signature, values).hex() diff --git a/scripts/grant_executor_permissions.py b/scripts/grant_executor_permissions.py index 2b7b77c9..e1ca4a5a 100644 --- a/scripts/grant_executor_permissions.py +++ b/scripts/grant_executor_permissions.py @@ -8,7 +8,7 @@ def main(): evm_script_executor = get_env("EVM_SCRIPT_EXECUTOR") lido_contracts = lido.contracts(network="mainnet") - lido_permissions = lido.permissions(contracts=lido_contracts) + lido_permissions = lido_contracts.permissions() required_permissions = [ lido_permissions.finance.CREATE_PAYMENTS_ROLE, @@ -17,9 +17,7 @@ def main(): acl = lido_contracts.aragon.acl - granted_permissions = lido_permissions.filter_granted( - permissions=required_permissions, address=evm_script_executor - ) + granted_permissions = lido_permissions.filter_granted(permissions=required_permissions, address=evm_script_executor) permissions_to_grant = list(set(required_permissions) - set(granted_permissions)) @@ -46,11 +44,11 @@ def main(): tx_params = { "from": deployer, - "gas_price": "100 gwei" + "gas_price": "100 gwei", # "priority_fee": "4 gwei", } vote_id = grant_executor_permissions( - acl=acl, + lido_contracts == lido_contracts, evm_script_executor=evm_script_executor, permissions_to_grant=permissions_to_grant, tx_params=tx_params, @@ -62,22 +60,19 @@ def get_permissions_to_grant(permissions, granted_permissions): return list(set(permissions) - set(granted_permissions)) -def grant_executor_permissions( - acl, evm_script_executor, permissions_to_grant, tx_params -): +def grant_executor_permissions(lido_contracts, evm_script_executor, permissions_to_grant, tx_params): + acl = lido_contracts.aragon.acl grant_permissions_evmscript = encode_call_script( [ ( acl.address, - acl.grantPermission.encode_input( - evm_script_executor, permission.app, permission.role - ), + acl.grantPermission.encode_input(evm_script_executor, permission.app, permission.role), ) for permission in permissions_to_grant ] ) - vote_id, _ = lido.create_voting( + vote_id, _ = lido_contracts.create_voting( evm_script=grant_permissions_evmscript, description="Grant permissions to {evm_script_executor}", tx_params=tx_params, diff --git a/scripts/migrate_reward_programs_to_allowed_recipient.py b/scripts/migrate_reward_programs_to_allowed_recipient.py new file mode 100644 index 00000000..13db54e1 --- /dev/null +++ b/scripts/migrate_reward_programs_to_allowed_recipient.py @@ -0,0 +1,94 @@ +from brownie import chain, network + +from utils.config import ( + get_is_live, + get_deployer_account, + prompt_bool, + get_network_name, +) +from utils import lido, deployed_easy_track, log + +from brownie import AllowedRecipientsBuilder + + +def main(): + network_name = get_network_name() + + if not (network_name == "goerli" or network_name == "goerli-fork"): + raise EnvironmentError("network is not supported") + + if not (network_name == "holesky" or network_name == "holesky-fork"): + raise EnvironmentError("network is not supported") + + recipients = [ + "0xbbe8dDEf5BF31b71Ff5DbE89635f9dB4DeFC667E", + "0x07fC01f46dC1348d7Ce43787b5Bbd52d8711a92D", + "0xa5F1d7D49F581136Cf6e58B32cBE9a2039C48bA1", + "0xDDFFac49946D1F6CE4d9CaF3B9C7d340d4848A1C", + "0xc6e2459991BfE27cca6d86722F35da23A1E4Cb97", + ] + titles = [ + "Default Reward Program", + "Happy", + "Sergey'2 #add RewardProgram", + "Jumpgate Test", + "tester", + ] + trusted_caller = "0x3eaE0B337413407FB3C65324735D797ddc7E071D" + limit = 10_000 * 1e18 + period = 1 + spent_amount = 0 + + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) + deployer = get_deployer_account(get_is_live(), network=network_name) + + easy_track = et_contracts.easy_track + evm_script_executor = et_contracts.evm_script_executor + + allowed_recipients_builder = AllowedRecipientsBuilder.at("0x1082512D1d60a0480445353eb55de451D261b684") + + log.br() + + log.nb("Current network", network.show_active(), color_hl=log.color_magenta) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) + log.ok("chain id", chain.id) + log.ok("Deployer", deployer) + + log.ok("Token", contracts.ldo) + log.ok("Trusted caller", trusted_caller) + log.ok("Limit", limit) + log.ok("Period", period) + log.ok("Spent amount", spent_amount) + + log.ok("Aragon Finance", contracts.aragon.finance) + log.ok("Aragon Agent", contracts.aragon.agent) + log.ok("EasyTrack", easy_track) + log.ok("EVMScript Executor", evm_script_executor) + + log.br() + + print("Proceed? [yes/no]: ") + + if not prompt_bool(): + log.nb("Aborting") + return + + tx_params = {"from": deployer, "priority_fee": "2 gwei", "max_fee": "50 gwei"} + + tx = allowed_recipients_builder.deployFullSetup( + trusted_caller, contracts.ldo, limit, period, recipients, titles, spent_amount, tx_params + ) + + registryAddress = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + topUpAddress = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + addRecipientAddress = tx.events["AddAllowedRecipientDeployed"]["addAllowedRecipient"] + removeAllowedRecipientAddress = tx.events["RemoveAllowedRecipientDeployed"]["removeAllowedRecipient"] + + log.ok("Allowed recipients easy track contracts have been deployed...") + log.nb("Deployed AllowedRecipientsRegistryDeployed", registryAddress) + log.nb("Deployed TopUpAllowedRecipientsDeployed", topUpAddress) + log.nb("Deployed AddAllowedRecipientDeployed", addRecipientAddress) + log.nb("Deployed RemoveAllowedRecipientDeployed", removeAllowedRecipientAddress) + + log.br() diff --git a/scripts/revoke_all_permissions.py b/scripts/revoke_all_permissions.py index b9a62546..340cecdc 100644 --- a/scripts/revoke_all_permissions.py +++ b/scripts/revoke_all_permissions.py @@ -8,11 +8,9 @@ def main(): evm_script_executor = get_env("EVM_SCRIPT_EXECUTOR") lido_contracts = lido.contracts(network="mainnet") - lido_permissions = lido.permissions(lido_contracts) + lido_permissions = lido_contracts.permissions() all_lido_permissions = lido_permissions.all() - granted_permissions = lido_permissions.filter_granted( - all_lido_permissions, evm_script_executor - ) + granted_permissions = lido_permissions.filter_granted(all_lido_permissions, evm_script_executor) print("List of all lido permissions:") for permission in all_lido_permissions: @@ -46,24 +44,19 @@ def main(): print(f"Vote successfully started! Vote id: {vote_id}") -def revoke_permissions( - lido_contracts, granted_permissions, evm_script_executor, tx_params -): +def revoke_permissions(lido_contracts, granted_permissions, evm_script_executor, tx_params): acl = lido_contracts.aragon.acl - revoke_permissions_evmscript = encode_call_script( [ ( acl.address, - acl.revokePermission.encode_input( - evm_script_executor, permission.app, permission.role - ), + acl.revokePermission.encode_input(evm_script_executor, permission.app, permission.role), ) for permission in granted_permissions ] ) - vote_id, _ = lido.create_voting( + vote_id, _ = lido_contracts.create_voting( evm_script=revoke_permissions_evmscript, description="Revoke all permissions from {evm_script_executor}", tx_params=tx_params, diff --git a/scripts/verify_simple_dvt_factories.sh b/scripts/verify_simple_dvt_factories.sh new file mode 100755 index 00000000..868cdb80 --- /dev/null +++ b/scripts/verify_simple_dvt_factories.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +RED='\033[0;31m' +ORANGE='\033[0;33m' +GREEN='\033[0;32m' +NC='\033[0m' + +if [[ "${TRACE-0}" == "1" ]]; then + set -o xtrace +fi + +envs=(REMOTE_RPC ETHERSCAN_TOKEN CONFIG ETHERSCAN_API) + +local_rpc_port=7776 + +_err() { + local message=$1 + + echo -e "${RED}Error:${NC} $message, aborting." >&2 + exit 1 +} + +for e in "${envs[@]}"; do + [[ "${!e:+isset}" == "isset" ]] || { _err "${e} env var is required but is not set"; } +done + +function start_fork() { + local_fork_command=$( + cat <<-_EOF_ | xargs | sed 's/ / /g' + yarn ganache --chain.vmErrorsOnRPCResponse true + --wallet.totalAccounts 10 --chain.chainId 1 + --fork.url ${REMOTE_RPC} + --miner.blockGasLimit 92000000 + --server.host 127.0.0.1 --server.port ${local_rpc_port} + --hardfork istanbul -d +_EOF_ + ) + + echo "Starting local fork \"${local_fork_command}\"" + (nc -vz 127.0.0.1 $local_rpc_port) &>/dev/null && kill -SIGTERM "$(lsof -t -i:$local_rpc_port)" + + $local_fork_command 1>>./logs 2>&1 & + fork_pid=$$ + echo "Ganache pid $fork_pid" + + sleep 10 +} + +start_fork + +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract AddNodeOperators --etherscan-api-url $ETHERSCAN_API --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract ActivateNodeOperators --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract DeactivateNodeOperators --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract SetVettedValidatorsLimits --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract IncreaseVettedValidatorsLimit --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract SetNodeOperatorNames --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract SetNodeOperatorRewardAddresses --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract ChangeNodeOperatorManagers --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache +echo "==========================================================" +./bytecode-verificator/bytecode_verificator.sh --solc-version 0.8.6 --remote-rpc-url $REMOTE_RPC --config-json $CONFIG --contract UpdateTargetValidatorLimits --etherscan-api-url $ETHERSCAN_API --skip-compilation --local-ganache \ No newline at end of file diff --git a/scripts/vote_for_reward_programs.py b/scripts/vote_for_reward_programs.py index 5642e4fb..b41e4c5e 100644 --- a/scripts/vote_for_reward_programs.py +++ b/scripts/vote_for_reward_programs.py @@ -2,37 +2,28 @@ from brownie import chain, network -from utils.vote_for_new_factories import ( - FactoryToAdd, - FactoryToRemove, - create_voting_on_new_factories -) +from utils.vote_for_new_factories import FactoryToAdd, create_voting_on_new_factories from utils.config import ( get_env, get_is_live, get_deployer_account, - network_name + get_network_name, ) -from utils import ( - lido, - deployed_easy_track, - log -) +from utils import lido, deployed_easy_track, log + def create_permission(contract, method): return contract.address + getattr(contract, method).signature[2:] -def start_vote( - netname: str, - deployer: Optional[str] -) -> int: - contracts = lido.contracts(network=netname) - et_contracts = deployed_easy_track.contracts(network=netname) - tx_params = { "from": deployer } - if (get_is_live()): +def start_vote(network_name: str, deployer: Optional[str]) -> int: + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) + + tx_params = {"from": deployer} + if get_is_live(): tx_params["priority_fee"] = "2 gwei" tx_params["max_fee"] = "300 gwei" @@ -50,7 +41,7 @@ def start_vote( log.br() log.nb("Current network", network.show_active(), color_hl=log.color_magenta) - log.nb("Using deployed addresses for", netname, color_hl=log.color_yellow) + log.nb("Using deployed addresses for", network_name, color_hl=log.color_yellow) log.ok("chain id", chain.id) log.ok("Deployer", deployer) log.ok("Reward programs type", prog_type) @@ -76,43 +67,37 @@ def start_vote( factories_to_add = [ FactoryToAdd( factory=reward_programs.add_reward_program, - permissions=create_permission( - reward_programs.reward_programs_registry, - "addRewardProgram" - ) + permissions=create_permission(reward_programs.reward_programs_registry, "addRewardProgram"), ), FactoryToAdd( factory=reward_programs.top_up_reward_programs, - permissions=create_permission( - contracts.aragon.finance, - "newImmediatePayment") - ), + permissions=create_permission(contracts.aragon.finance, "newImmediatePayment"), + ), FactoryToAdd( factory=reward_programs.remove_reward_program, - permissions=create_permission( - reward_programs.reward_programs_registry, - "removeRewardProgram" - ) - ) + permissions=create_permission(reward_programs.reward_programs_registry, "removeRewardProgram"), + ), ] vote_id = create_voting_on_new_factories( easy_track=easy_track, factories_to_remove=factories_to_remove, factories_to_add=factories_to_add, - network=netname, - tx_params=tx_params + network=network_name, + tx_params=tx_params, ) return vote_id + def main(): - netname = "goerli" if network_name().split('-')[0] == "goerli" else "mainnet" - deployer = get_deployer_account(get_is_live(), network=netname) + network_name = get_network_name() + + deployer = get_deployer_account(get_is_live(), network=network_name) - vote_id = start_vote(netname, deployer) + vote_id = start_vote(network_name, deployer) - vote_id >= 0 and print(f'Vote successfully started! Vote id: {vote_id}.') + vote_id >= 0 and print(f"Vote successfully started! Vote id: {vote_id}.") print("Hit to quit script") input() diff --git a/slither.config.json b/slither.config.json new file mode 100644 index 00000000..e5347201 --- /dev/null +++ b/slither.config.json @@ -0,0 +1,7 @@ +{ + "exclude_informational": true, + "exclude_low": true, + "exclude_medium": false, + "exclude_high": false, + "filter_paths": "(.*test.*/|.*template/|.*mocks/|node_modules/|.*brownie/|.*dependencies/)" +} diff --git a/specification.md b/specification.md index c4597f9c..6844a50f 100644 --- a/specification.md +++ b/specification.md @@ -296,11 +296,11 @@ Contains method to execute EVMScripts. Inherits from OpenZeppelin's `Ownable` co ``` EVM_SCRIPT -> SPEC_ID | SPEC_ID EVM_SCRIPTS_LIST EVM_SCRIPTS_LIST -> EVM_SCRIPT_ITEM | EVM_SCRIPTS_LIST -EVM_SCRIPT_ITEM -> ADDRESS CALL_DATA_LENGTH CALL_DATA +EVM_SCRIPT_ITEM -> ADDRESS CALLDATA_LENGTH CALLDATA SPEC_ID -> uint32 ADDRESS -> address -CALL_DATA_LENGTH -> uint32 -CALL_DATA -> bytes of length CALL_DATA_LENGTH +CALLDATA_LENGTH -> uint32 +CALLDATA -> bytes of length CALLDATA_LENGTH ``` ### Methods diff --git a/tests/conftest.py b/tests/conftest.py index 610c2f32..9630e90c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,9 +7,7 @@ import constants from utils.lido import contracts -from utils import test_helpers - -brownie.web3.enable_strict_bytes_type_checking() +from utils import deployed_date_time #################################### # Brownie Blockchain State Snapshots @@ -21,13 +19,11 @@ @pytest.fixture(scope="module", autouse=True) def mod_isolation(module_isolation): """Snapshot ganache at start of module.""" - pass @pytest.fixture(autouse=True) def isolation(fn_isolation): """Snapshot ganache before every test function call.""" - pass ############## @@ -84,8 +80,7 @@ def lego_program(accounts): @pytest.fixture(scope="module") def lido_contracts(): - # Have this as a fixture to cache the result. - return contracts() + return contracts(network=brownie.network.show_active()) @pytest.fixture(scope="module") @@ -105,7 +100,7 @@ def evm_script_factories_registry(owner, EVMScriptFactoriesRegistry): @pytest.fixture(scope="module") -def easy_track(owner, ldo, voting, evm_script_executor_stub, EasyTrack): +def easy_track(owner, ldo, voting, EasyTrack, EVMScriptExecutor, calls_script): contract = owner.deploy( EasyTrack, ldo, @@ -114,19 +109,18 @@ def easy_track(owner, ldo, voting, evm_script_executor_stub, EasyTrack): constants.MAX_MOTIONS_LIMIT, constants.DEFAULT_OBJECTIONS_THRESHOLD, ) - contract.setEVMScriptExecutor(evm_script_executor_stub, {"from": voting}) + evm_script_executor = owner.deploy(EVMScriptExecutor, calls_script, contract) + contract.setEVMScriptExecutor(evm_script_executor, {"from": voting}) return contract @pytest.fixture(scope="module") def evm_script_executor(owner, easy_track, calls_script, EVMScriptExecutor): - return owner.deploy(EVMScriptExecutor, calls_script, easy_track) + return EVMScriptExecutor.at(easy_track.evmScriptExecutor()) @pytest.fixture(scope="module") -def reward_programs_registry( - owner, voting, evm_script_executor_stub, RewardProgramsRegistry -): +def reward_programs_registry(owner, voting, evm_script_executor_stub, RewardProgramsRegistry): return owner.deploy( RewardProgramsRegistry, voting, @@ -141,9 +135,7 @@ def reward_programs_registry( @pytest.fixture(scope="module") -def increase_node_operator_staking_limit( - owner, node_operators_registry_stub, IncreaseNodeOperatorStakingLimit -): +def increase_node_operator_staking_limit(owner, node_operators_registry_stub, IncreaseNodeOperatorStakingLimit): return owner.deploy(IncreaseNodeOperatorStakingLimit, node_operators_registry_stub) @@ -151,23 +143,34 @@ def increase_node_operator_staking_limit( def add_reward_program(owner, reward_programs_registry, AddRewardProgram): return owner.deploy(AddRewardProgram, owner, reward_programs_registry) + @pytest.fixture(scope="module") def remove_reward_program(owner, reward_programs_registry, RemoveRewardProgram): return owner.deploy(RemoveRewardProgram, owner, reward_programs_registry) + @pytest.fixture(scope="module") -def top_up_reward_programs( - owner, finance, ldo, reward_programs_registry, TopUpRewardPrograms -): - return owner.deploy( - TopUpRewardPrograms, owner, reward_programs_registry, finance, ldo - ) +def top_up_reward_programs(owner, finance, ldo, reward_programs_registry, TopUpRewardPrograms): + return owner.deploy(TopUpRewardPrograms, owner, reward_programs_registry, finance, ldo) + @pytest.fixture(scope="module") def top_up_lego_program(owner, finance, lego_program, TopUpLegoProgram): return owner.deploy(TopUpLegoProgram, owner, finance, lego_program) +@pytest.fixture(scope="module") +def add_allowed_recipients(owner, allowed_recipients_registry, AddAllowedRecipient): + (registry, _, _, _, _, _) = allowed_recipients_registry + return owner.deploy(AddAllowedRecipient, owner, registry) + + +@pytest.fixture(scope="module") +def remove_allowed_recipients(owner, allowed_recipients_registry, RemoveAllowedRecipient): + (registry, _, _, _, _, _) = allowed_recipients_registry + return owner.deploy(RemoveAllowedRecipient, owner, registry) + + ############ # MOCKS AND TEST WRAPPERS ############ @@ -203,6 +206,79 @@ def evm_script_executor_stub(owner, EVMScriptExecutorStub): return owner.deploy(EVMScriptExecutorStub) +@pytest.fixture(scope="module") +def limits_checker(owner, accounts, LimitsChecker, bokkyPooBahsDateTimeContract): + set_parameters_role_holder = accounts[8] + update_spent_amount_role_holder = accounts[9] + limits_checker = owner.deploy( + LimitsChecker, + [set_parameters_role_holder], + [update_spent_amount_role_holder], + bokkyPooBahsDateTimeContract, + ) + return (limits_checker, set_parameters_role_holder, update_spent_amount_role_holder) + + +@pytest.fixture(scope="module") +def limits_checker_with_private_method_exposed( + owner, accounts, LimitsCheckerWithPrivateViewsExposed, bokkyPooBahsDateTimeContract +): + set_parameters_role_holder = accounts[8] + update_spent_amount_role_holder = accounts[9] + limits_checker = owner.deploy( + LimitsCheckerWithPrivateViewsExposed, + [set_parameters_role_holder], + [update_spent_amount_role_holder], + bokkyPooBahsDateTimeContract, + ) + return (limits_checker, set_parameters_role_holder, update_spent_amount_role_holder) + + +@pytest.fixture(scope="module") +def allowed_recipients_registry(AllowedRecipientsRegistry, bokkyPooBahsDateTimeContract, owner, accounts): + add_recipient_role_holder = accounts[6] + remove_recipient_role_holder = accounts[7] + set_limit_role_holder = accounts[8] + update_spent_role_holder = accounts[9] + + registry = owner.deploy( + AllowedRecipientsRegistry, + owner, + [add_recipient_role_holder], + [remove_recipient_role_holder], + [set_limit_role_holder], + [update_spent_role_holder], + bokkyPooBahsDateTimeContract, + ) + + return ( + registry, + owner, + add_recipient_role_holder, + remove_recipient_role_holder, + set_limit_role_holder, + update_spent_role_holder, + ) + + +@pytest.fixture(scope="module") +def top_up_allowed_recipients( + allowed_recipients_registry, + accounts, + finance, + ldo, + easy_track, + TopUpAllowedRecipients, +): + (registry, owner, _, _, _, _) = allowed_recipients_registry + + trusted_caller = accounts[4] + + top_up_factory = owner.deploy(TopUpAllowedRecipients, trusted_caller, registry, finance, ldo, easy_track) + + return top_up_factory + + ########## # INTERFACES ########## @@ -219,7 +295,10 @@ def steth(lido_contracts): @pytest.fixture(scope="module") -def node_operators_registry(lido_contracts): +def node_operators_registry(lido_contracts, agent): + for i in range(10): + if not lido_contracts.node_operators_registry.getNodeOperatorIsActive(i): + lido_contracts.node_operators_registry.activateNodeOperator(i, {"from": agent}) return lido_contracts.node_operators_registry @@ -253,6 +332,21 @@ def calls_script(lido_contracts): return lido_contracts.aragon.calls_script +@pytest.fixture(scope="module") +def kernel(lido_contracts): + return lido_contracts.aragon.kernel + + +@pytest.fixture(scope="module") +def staking_router(lido_contracts): + return lido_contracts.staking_router + + +@pytest.fixture(scope="module") +def locator(lido_contracts): + return lido_contracts.locator + + ######################### # State Changing Fixtures ######################### @@ -285,41 +379,47 @@ def method(account, amount): return method + class Helpers: @staticmethod - def execute_vote(accounts, vote_id, dao_voting, ldo_vote_executors_for_tests, topup='0.1 ether'): + def execute_vote(accounts, vote_id, dao_voting, ldo_vote_executors_for_tests, topup="0.1 ether"): if dao_voting.getVote(vote_id)[0]: for holder_addr in ldo_vote_executors_for_tests: - print('voting from acct:', holder_addr) + print("voting from acct:", holder_addr) accounts[0].transfer(holder_addr, topup) account = accounts.at(holder_addr, force=True) - dao_voting.vote(vote_id, True, False, {'from': account}) + dao_voting.vote(vote_id, True, False, {"from": account}) # wait for the vote to end chain.sleep(3 * 60 * 60 * 24) chain.mine() assert dao_voting.canExecute(vote_id) - tx = dao_voting.executeVote(vote_id, {'from': accounts[0]}) + tx = dao_voting.executeVote(vote_id, {"from": accounts[0]}) - print(f'vote #{vote_id} executed') + print(f"vote #{vote_id} executed") return tx -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def helpers(): return Helpers -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def vote_id_from_env() -> Optional[int]: _env_name = "OMNIBUS_VOTE_ID" if os.getenv(_env_name): try: vote_id = int(os.getenv(_env_name)) - print(f'OMNIBUS_VOTE_ID env var is set, using existing vote #{vote_id}') + print(f"OMNIBUS_VOTE_ID env var is set, using existing vote #{vote_id}") return vote_id except: pass return None + + +@pytest.fixture(scope="module") +def bokkyPooBahsDateTimeContract(): + return deployed_date_time.date_time_contract(network=brownie.network.show_active()) diff --git a/tests/evm_script_factories/test_activate_node_operators.py b/tests/evm_script_factories/test_activate_node_operators.py new file mode 100644 index 00000000..79dd4466 --- /dev/null +++ b/tests/evm_script_factories/test_activate_node_operators.py @@ -0,0 +1,196 @@ +import pytest +from eth_abi import encode +from brownie import reverts, ActivateNodeOperators, web3, ZERO_ADDRESS +from utils.permission_parameters import Op, Param, encode_permission_params + +from utils.evm_script import encode_call_script + +MANAGERS = [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", +] + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,address)[]"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def activate_node_operators_factory(owner, node_operators_registry, acl, voting): + acl.grantPermission( + voting, + node_operators_registry, + web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE").hex(), + {"from": voting}, + ) + for id, manager in enumerate(MANAGERS): + node_operators_registry.deactivateNodeOperator(id, {"from": voting}) + return ActivateNodeOperators.deploy(owner, node_operators_registry, acl, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, acl, activate_node_operators_factory): + "Must deploy contract with correct data" + assert activate_node_operators_factory.trustedCaller() == owner + assert activate_node_operators_factory.nodeOperatorsRegistry() == node_operators_registry + assert activate_node_operators_factory.acl() == acl + + +def test_create_evm_script_called_by_stranger(stranger, activate_node_operators_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + activate_node_operators_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_empty_calldata(owner, activate_node_operators_factory): + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([]) + activate_node_operators_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_non_sorted_calldata(owner, activate_node_operators_factory): + "Must revert with message 'NODE_OPERATORS_IS_NOT_SORTED' when operator ids isn't sorted" + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(1, MANAGERS[1]), (0, MANAGERS[0])]) + activate_node_operators_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(0, MANAGERS[0]), (0, MANAGERS[1])]) + activate_node_operators_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_manager_has_duplicates(owner, activate_node_operators_factory): + "Must revert with message 'MANAGER_ADDRESSES_HAS_DUPLICATE' when managers had duplicates" + + with reverts("MANAGER_ADDRESSES_HAS_DUPLICATE"): + NON_SORTED_CALLDATA = create_calldata([(0, MANAGERS[0]), (1, MANAGERS[0])]) + activate_node_operators_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_operator_id_out_of_range(owner, activate_node_operators_factory, node_operators_registry): + "Must revert with message 'NODE_OPERATOR_INDEX_OUT_OF_RANGE' when operator id gt operators count" + + with reverts("NODE_OPERATOR_INDEX_OUT_OF_RANGE"): + node_operators_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata( + [ + ( + node_operators_count, + "0x0000000000000000000000000000000000000000", + ) + ] + ) + activate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_node_operator_invalid_state(owner, activate_node_operators_factory): + "Must revert with message 'WRONG_OPERATOR_ACTIVE_STATE' when operator already active" + + with reverts("WRONG_OPERATOR_ACTIVE_STATE"): + CALLDATA = create_calldata([(2, MANAGERS[0])]) + activate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_already_has_permission(owner, activate_node_operators_factory, node_operators_registry, acl, voting): + "Must revert with message 'MANAGER_ALREADY_HAS_ROLE' when manager has MANAGE_SIGNING_KEYS role" + + acl.grantPermission( + MANAGERS[0], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + {"from": voting}, + ) + CALLDATA = create_calldata([(0, MANAGERS[0])]) + with reverts("MANAGER_ALREADY_HAS_ROLE"): + activate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_already_has_permission_for_node_operator( + owner, activate_node_operators_factory, node_operators_registry, acl, voting +): + "Must revert with message 'MANAGER_ALREADY_HAS_ROLE' when manager has MANAGE_SIGNING_KEYS role" + + acl.grantPermissionP( + MANAGERS[0], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, 0)]), + {"from": voting}, + ) + CALLDATA = create_calldata([(0, MANAGERS[0])]) + with reverts("MANAGER_ALREADY_HAS_ROLE"): + activate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_already_has_permission_for_different_node_operator( + owner, activate_node_operators_factory, node_operators_registry, acl, voting +): + "Must revert with message 'MANAGER_ALREADY_HAS_ROLE' when manager has MANAGE_SIGNING_KEYS role" + + acl.grantPermissionP( + MANAGERS[0], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, 1)]), + {"from": voting}, + ) + CALLDATA = create_calldata([(0, MANAGERS[0])]) + with reverts("MANAGER_ALREADY_HAS_ROLE"): + activate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_zero_manager(owner, activate_node_operators_factory): + "Must revert with message 'ZERO_MANAGER_ADDRESS' when manager is zero address" + + with reverts("ZERO_MANAGER_ADDRESS"): + CALLDATA = create_calldata( + [ + (0, ZERO_ADDRESS), + ] + ) + activate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script(owner, activate_node_operators_factory, node_operators_registry, acl): + "Must create correct EVMScript if all requirements are met" + input_params = [(id, manager) for id, manager in enumerate(MANAGERS)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = activate_node_operators_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + scripts = [] + for input_param in input_params: + scripts.append( + ( + node_operators_registry.address, + node_operators_registry.activateNodeOperator.encode_input(input_param[0]), + ) + ) + scripts.append( + ( + acl.address, + acl.grantPermissionP.encode_input( + input_param[1], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, input_param[0])]), + ), + ) + ) + expected_evm_script = encode_call_script(scripts) + + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(activate_node_operators_factory): + "Must decode EVMScript call data correctly" + input_params = [(id, manager) for id, manager in enumerate(MANAGERS)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert activate_node_operators_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_add_allowed_recipient.py b/tests/evm_script_factories/test_add_allowed_recipient.py new file mode 100644 index 00000000..f2292cb2 --- /dev/null +++ b/tests/evm_script_factories/test_add_allowed_recipient.py @@ -0,0 +1,95 @@ +from brownie import ZERO_ADDRESS, reverts +from utils.evm_script import encode_calldata, encode_call_script + +EVM_SCRIPT_CALLDATA_TITLE = "TITLE" + + +def test_deploy(owner, AddAllowedRecipient, allowed_recipients_registry): + "Must deploy contract with correct data" + (registry, _, _, _, _, _) = allowed_recipients_registry + contract = owner.deploy(AddAllowedRecipient, owner, registry) + + assert contract.trustedCaller() == owner + assert contract.allowedRecipientsRegistry() == registry + + +def test_deploy_zero_trusted_caller(owner, AddAllowedRecipient, allowed_recipients_registry): + "Must revert deploying a contract with zero trusted caller" + (registry, _, _, _, _, _) = allowed_recipients_registry + + with reverts("TRUSTED_CALLER_IS_ZERO_ADDRESS"): + owner.deploy(AddAllowedRecipient, ZERO_ADDRESS, registry) + + +def test_deploy_zero_allowed_recipient_registry(owner, AddAllowedRecipient): + "Must deploy contract with zero allowed recipient registry" + contract = owner.deploy(AddAllowedRecipient, owner, ZERO_ADDRESS) + + assert contract.allowedRecipientsRegistry() == ZERO_ADDRESS + + +def test_create_evm_script_is_permissionless(owner, stranger, add_allowed_recipients): + call_data = create_calldata(owner.address) + add_allowed_recipients.createEVMScript(owner, call_data, {"from": stranger}) + + +def test_decode_evm_script_calldata_is_permissionless(stranger, add_allowed_recipients): + call_data = create_calldata(stranger.address) + add_allowed_recipients.decodeEVMScriptCallData(call_data, {"from": stranger}) + + +def test_only_trusted_caller_can_be_creator(owner, stranger, add_allowed_recipients): + call_data = create_calldata(owner.address) + + with reverts("CALLER_IS_FORBIDDEN"): + add_allowed_recipients.createEVMScript(stranger, call_data, {"from": owner}) + + add_allowed_recipients.createEVMScript(owner, call_data, {"from": owner}) + + +def test_revert_create_evm_script_with_empty_calldata(owner, add_allowed_recipients): + with reverts(): + add_allowed_recipients.createEVMScript(owner, "0x", {"from": owner}) + + +def test_revert_create_evm_script_with_empty_recipient_address(owner, add_allowed_recipients): + call_data = create_calldata(ZERO_ADDRESS) + with reverts("RECIPIENT_ADDRESS_IS_ZERO_ADDRESS"): + add_allowed_recipients.createEVMScript(owner, call_data, {"from": owner}) + + +def test_revert_recipient_already_added(owner, stranger, add_allowed_recipients, allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + registry.addRecipient(stranger, "Stranger", {"from": add_recipient_role_holder}) + call_data = create_calldata(stranger.address) + + with reverts("ALLOWED_RECIPIENT_ALREADY_ADDED"): + add_allowed_recipients.createEVMScript(owner, call_data) + + +def test_create_evm_script_correctly(owner, add_allowed_recipients, allowed_recipients_registry): + call_data = create_calldata(owner.address) + evm_script = add_allowed_recipients.createEVMScript(owner, call_data) + (registry, _, _, _, _, _) = allowed_recipients_registry + expected_evm_script = encode_call_script( + [ + ( + registry.address, + registry.addRecipient.encode_input(owner, EVM_SCRIPT_CALLDATA_TITLE), + ) + ] + ) + + assert evm_script == expected_evm_script + + +def test_decode_evm_script_calldata_correctly(owner, add_allowed_recipients): + call_data = create_calldata(owner.address) + + (address, title) = add_allowed_recipients.decodeEVMScriptCallData(call_data) + assert address == owner.address + assert title == EVM_SCRIPT_CALLDATA_TITLE + + +def create_calldata(recipient): + return encode_calldata(["address", "string"], [recipient, EVM_SCRIPT_CALLDATA_TITLE]) diff --git a/tests/evm_script_factories/test_add_node_operators.py b/tests/evm_script_factories/test_add_node_operators.py new file mode 100644 index 00000000..df2135c7 --- /dev/null +++ b/tests/evm_script_factories/test_add_node_operators.py @@ -0,0 +1,237 @@ +import pytest +from eth_abi import encode +from brownie import reverts, AddNodeOperators, web3, ZERO_ADDRESS + +from utils.evm_script import encode_call_script +from utils.permission_parameters import Op, Param, encode_permission_params + +OPERATOR_NAMES = [ + "Name 1", + "Name 2", +] + +REWARD_ADDRESSES = [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", +] + +MANAGERS = [ + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", +] + + +def create_calldata(data): + return ( + "0x" + + encode( + ["uint256", "(string,address,address)[]"], + data, + ).hex() + ) + + +@pytest.fixture(scope="module") +def add_node_operators_factory(owner, node_operators_registry, acl, steth): + return AddNodeOperators.deploy(owner, node_operators_registry, acl, steth, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, acl, add_node_operators_factory): + "Must deploy contract with correct data" + assert add_node_operators_factory.trustedCaller() == owner + assert add_node_operators_factory.nodeOperatorsRegistry() == node_operators_registry + assert add_node_operators_factory.acl() == acl + + +def test_create_evm_script_called_by_stranger(stranger, add_node_operators_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + add_node_operators_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_node_operators_count(owner, add_node_operators_factory): + "Must revert with message 'NODE_OPERATORS_COUNT_MISMATCH' when node operators registry operators count passed wrong" + + with reverts("NODE_OPERATORS_COUNT_MISMATCH"): + CALLDATA = create_calldata( + [0, [(OPERATOR_NAMES[0], REWARD_ADDRESSES[0], MANAGERS[0])]], + ) + add_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_empty_calldata(owner, add_node_operators_factory, node_operators_registry): + no_count = node_operators_registry.getNodeOperatorsCount() + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([0, []]) + add_node_operators_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_manager_has_duplicate(owner, add_node_operators_factory, node_operators_registry): + "Must revert with message 'MANAGER_ADDRESSES_HAS_DUPLICATE' when menager address has duplicate" + no_count = node_operators_registry.getNodeOperatorsCount() + with reverts("MANAGER_ADDRESSES_HAS_DUPLICATE"): + CALLDATA = create_calldata( + [ + no_count, + [ + (OPERATOR_NAMES[0], REWARD_ADDRESSES[0], MANAGERS[0]), + (OPERATOR_NAMES[1], REWARD_ADDRESSES[1], MANAGERS[0]), + ], + ] + ) + add_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_already_has_permission(owner, add_node_operators_factory, node_operators_registry, acl, voting): + "Must revert with message 'MANAGER_ALREADY_HAS_ROLE' when manager has MANAGE_SIGNING_KEYS role" + no_count = node_operators_registry.getNodeOperatorsCount() + + acl.grantPermission( + MANAGERS[0], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + {"from": voting}, + ) + + with reverts("MANAGER_ALREADY_HAS_ROLE"): + CALLDATA = create_calldata( + [ + no_count, + [ + (OPERATOR_NAMES[0], REWARD_ADDRESSES[0], MANAGERS[0]), + ], + ] + ) + add_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_already_has_permission_for_node_operator( + owner, add_node_operators_factory, node_operators_registry, acl, voting +): + "Must revert with message 'MANAGER_ALREADY_HAS_ROLE' when manager has MANAGE_SIGNING_KEYS role with parameter" + no_count = node_operators_registry.getNodeOperatorsCount() + + acl.grantPermissionP( + MANAGERS[0], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, 0)]), + {"from": voting}, + ) + with reverts("MANAGER_ALREADY_HAS_ROLE"): + CALLDATA = create_calldata( + [ + no_count, + [ + (OPERATOR_NAMES[0], REWARD_ADDRESSES[0], MANAGERS[0]), + ], + ] + ) + add_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_zero_manager(owner, add_node_operators_factory, node_operators_registry): + "Must revert with message 'ZERO_MANAGER_ADDRESS' when manager is zero address" + no_count = node_operators_registry.getNodeOperatorsCount() + + with reverts("ZERO_MANAGER_ADDRESS"): + CALLDATA = create_calldata( + [ + no_count, + [ + (OPERATOR_NAMES[0], REWARD_ADDRESSES[0], ZERO_ADDRESS), + ], + ] + ) + add_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_zero_reward_address(owner, add_node_operators_factory, node_operators_registry): + "Must revert with message 'ZERO_REWARD_ADDRESS' when reward address is zero address" + no_count = node_operators_registry.getNodeOperatorsCount() + + with reverts("ZERO_REWARD_ADDRESS"): + CALLDATA = create_calldata( + [ + no_count, + [ + (OPERATOR_NAMES[0], ZERO_ADDRESS, MANAGERS[0]), + ], + ] + ) + add_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_lido_reward_address(owner, add_node_operators_factory, node_operators_registry, steth): + "Must revert with message 'LIDO_REWARD_ADDRESS' when reward address is lido address" + no_count = node_operators_registry.getNodeOperatorsCount() + + with reverts("LIDO_REWARD_ADDRESS"): + CALLDATA = create_calldata( + [ + no_count, + [ + (OPERATOR_NAMES[0], steth.address, MANAGERS[0]), + ], + ] + ) + add_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script(owner, add_node_operators_factory, node_operators_registry, acl): + "Must create correct EVMScript if all requirements are met" + + input_params = [ + (OPERATOR_NAMES[0], REWARD_ADDRESSES[0], MANAGERS[0]), + (OPERATOR_NAMES[1], REWARD_ADDRESSES[1], MANAGERS[1]), + ] + + no_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata( + [ + no_count, + input_params, + ] + ) + evm_script = add_node_operators_factory.createEVMScript(owner, CALLDATA) + + no_count = node_operators_registry.getNodeOperatorsCount() + + scripts = [] + for id, input_param in enumerate(input_params): + scripts.append( + ( + node_operators_registry.address, + node_operators_registry.addNodeOperator.encode_input(input_param[0], input_param[1]), + ) + ) + scripts.append( + ( + acl.address, + acl.grantPermissionP.encode_input( + input_param[2], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, no_count + id)]), + ), + ) + ) + expected_evm_script = encode_call_script(scripts) + + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(node_operators_registry, add_node_operators_factory): + "Must decode EVMScript call data correctly" + no_count = node_operators_registry.getNodeOperatorsCount() + input_params = [ + no_count, + [ + (OPERATOR_NAMES[0], REWARD_ADDRESSES[0], MANAGERS[0]), + (OPERATOR_NAMES[1], REWARD_ADDRESSES[1], MANAGERS[1]), + ], + ] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert add_node_operators_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_add_reward_program.py b/tests/evm_script_factories/test_add_reward_program.py index a84c59b1..a181bea0 100644 --- a/tests/evm_script_factories/test_add_reward_program.py +++ b/tests/evm_script_factories/test_add_reward_program.py @@ -1,15 +1,10 @@ -from eth_abi import encode_single +from eth_abi import encode from brownie import reverts from utils.evm_script import encode_call_script REWARD_PROGRAM_ADDRESS = "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF" REWARD_PROGRAM_TITLE = "New Reward Program" -EVM_SCRIPT_CALL_DATA = ( - "0x" - + encode_single( - "(address,string)", [REWARD_PROGRAM_ADDRESS, REWARD_PROGRAM_TITLE] - ).hex() -) +EVM_SCRIPT_CALLDATA = "0x" + encode(["address", "string"], [REWARD_PROGRAM_ADDRESS, REWARD_PROGRAM_TITLE]).hex() def test_deploy(owner, reward_programs_registry, AddRewardProgram): @@ -22,7 +17,7 @@ def test_deploy(owner, reward_programs_registry, AddRewardProgram): def test_create_evm_script_called_by_stranger(stranger, add_reward_program): "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" with reverts("CALLER_IS_FORBIDDEN"): - add_reward_program.createEVMScript(stranger, EVM_SCRIPT_CALL_DATA) + add_reward_program.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) def test_create_evm_script_reward_program_already_added( @@ -38,20 +33,18 @@ def test_create_evm_script_reward_program_already_added( with reverts("REWARD_PROGRAM_ALREADY_ADDED"): add_reward_program.createEVMScript( owner, - EVM_SCRIPT_CALL_DATA, + EVM_SCRIPT_CALLDATA, ) def test_create_evm_script(owner, add_reward_program, reward_programs_registry): "Must create correct EVMScript if all requirements are met" - evm_script = add_reward_program.createEVMScript(owner, EVM_SCRIPT_CALL_DATA) + evm_script = add_reward_program.createEVMScript(owner, EVM_SCRIPT_CALLDATA) expected_evm_script = encode_call_script( [ ( reward_programs_registry.address, - reward_programs_registry.addRewardProgram.encode_input( - REWARD_PROGRAM_ADDRESS, REWARD_PROGRAM_TITLE - ), + reward_programs_registry.addRewardProgram.encode_input(REWARD_PROGRAM_ADDRESS, REWARD_PROGRAM_TITLE), ) ] ) @@ -61,7 +54,7 @@ def test_create_evm_script(owner, add_reward_program, reward_programs_registry): def test_decode_evm_script_call_data(add_reward_program): "Must decode EVMScript call data correctly" - assert add_reward_program.decodeEVMScriptCallData(EVM_SCRIPT_CALL_DATA) == ( + assert add_reward_program.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == ( REWARD_PROGRAM_ADDRESS, REWARD_PROGRAM_TITLE, ) diff --git a/tests/evm_script_factories/test_change_node_operator_manager.py b/tests/evm_script_factories/test_change_node_operator_manager.py new file mode 100644 index 00000000..2fd876f2 --- /dev/null +++ b/tests/evm_script_factories/test_change_node_operator_manager.py @@ -0,0 +1,267 @@ +import pytest +from eth_abi import encode +from brownie import reverts, ChangeNodeOperatorManagers, web3, ZERO_ADDRESS +from utils.permission_parameters import Op, Param, encode_permission_params + +from utils.evm_script import encode_call_script + +MANAGERS = [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", +] + +NEW_MANAGERS = [ + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", +] + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,address,address)[]"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def change_node_operator_managers_factory(owner, node_operators_registry, acl, voting): + acl.grantPermission( + voting, + node_operators_registry, + web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE").hex(), + {"from": voting}, + ) + for id, manager in enumerate(MANAGERS): + acl.grantPermissionP( + manager, + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, id)]), + {"from": voting}, + ) + + return ChangeNodeOperatorManagers.deploy(owner, node_operators_registry, acl, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, change_node_operator_managers_factory): + "Must deploy contract with correct data" + assert change_node_operator_managers_factory.trustedCaller() == owner + assert change_node_operator_managers_factory.nodeOperatorsRegistry() == node_operators_registry + + +def test_create_evm_script_called_by_stranger(stranger, change_node_operator_managers_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + change_node_operator_managers_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_empty_calldata(owner, change_node_operator_managers_factory): + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([]) + change_node_operator_managers_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_non_sorted_calldata(owner, change_node_operator_managers_factory): + "Must revert with message 'NODE_OPERATORS_IS_NOT_SORTED' when operator ids isn't sorted" + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata( + [ + (1, MANAGERS[1], NEW_MANAGERS[1]), + (0, MANAGERS[0], NEW_MANAGERS[0]), + ] + ) + change_node_operator_managers_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata( + [ + (0, MANAGERS[0], NEW_MANAGERS[0]), + (0, MANAGERS[0], NEW_MANAGERS[1]), + ] + ) + change_node_operator_managers_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_operator_id_out_of_range(owner, change_node_operator_managers_factory, node_operators_registry): + "Must revert with message 'NODE_OPERATOR_INDEX_OUT_OF_RANGE' when operator id gt operators count" + + with reverts("NODE_OPERATOR_INDEX_OUT_OF_RANGE"): + node_operators_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata([(node_operators_count, MANAGERS[0], NEW_MANAGERS[0])]) + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_duplicate_manager(owner, change_node_operator_managers_factory): + "Must revert with message 'MANAGER_ADDRESSES_HAS_DUPLICATE' when new maanger has duplicates" + + with reverts("MANAGER_ADDRESSES_HAS_DUPLICATE"): + CALLDATA = create_calldata( + [ + (0, MANAGERS[1], NEW_MANAGERS[1]), + (1, MANAGERS[0], NEW_MANAGERS[1]), + ] + ) + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_has_no_role(owner, change_node_operator_managers_factory): + "Must revert with message 'OLD_MANAGER_HAS_NO_ROLE' when manager has no MANAGE_SIGNING_KEYS role" + + CALLDATA = create_calldata([(2, MANAGERS[0], NEW_MANAGERS[0])]) + with reverts("OLD_MANAGER_HAS_NO_ROLE"): + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_has_another_role_operator( + owner, change_node_operator_managers_factory, node_operators_registry, acl, voting +): + "Must revert with message 'OLD_MANAGER_HAS_NO_ROLE' when manager has MANAGE_SIGNING_KEYS role with wrong param operator" + + manager = "0x0000000000000000000000000000000000000001" + new_manager = "0x0000000000000000000000000000000000000005" + operator = 2 + + acl.grantPermissionP( + manager, + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.NEQ, operator)]), + {"from": voting}, + ) + + CALLDATA = create_calldata([(operator, manager, new_manager)]) + with reverts("OLD_MANAGER_HAS_NO_ROLE"): + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_has_role_for_another_operator( + owner, change_node_operator_managers_factory, node_operators_registry, acl, voting +): + "Must revert with message 'OLD_MANAGER_HAS_NO_ROLE' when manager has MANAGE_SIGNING_KEYS role with wrong param operator" + + manager = "0x0000000000000000000000000000000000000001" + new_manager = "0x0000000000000000000000000000000000000005" + operator = 2 + + acl.grantPermissionP( + manager, + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, operator + 1)]), + {"from": voting}, + ) + + CALLDATA = create_calldata([(operator, manager, new_manager)]) + with reverts("OLD_MANAGER_HAS_NO_ROLE"): + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_old_manager_has_general_permission( + owner, change_node_operator_managers_factory, node_operators_registry, acl, voting +): + "Must revert with message 'OLD_MANAGER_HAS_NO_ROLE' when manager has general MANAGE_SIGNING_KEYS role" + + manager = "0x0000000000000000000000000000000000000001" + new_manager = "0x0000000000000000000000000000000000000005" + operator = 2 + + acl.grantPermission( + manager, + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + {"from": voting}, + ) + + CALLDATA = create_calldata([(operator, manager, new_manager)]) + with reverts("OLD_MANAGER_HAS_NO_ROLE"): + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_zero_manager(owner, change_node_operator_managers_factory): + "Must revert with message 'ZERO_MANAGER_ADDRESS' when manager is zero address" + + CALLDATA = create_calldata([(0, MANAGERS[0], ZERO_ADDRESS)]) + with reverts("ZERO_MANAGER_ADDRESS"): + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_new_manager_has_permission(owner, change_node_operator_managers_factory): + "Must revert with message 'MANAGER_ALREADY_HAS_ROLE' when new manager already has permission" + + CALLDATA = create_calldata([(0, MANAGERS[0], MANAGERS[1])]) + with reverts("MANAGER_ALREADY_HAS_ROLE"): + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_new_manager_has_general_permission( + owner, change_node_operator_managers_factory, acl, voting, node_operators_registry +): + "Must revert with message 'MANAGER_ALREADY_HAS_ROLE' when new manager already has general permission" + acl.grantPermission( + NEW_MANAGERS[0], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + {"from": voting}, + ) + CALLDATA = create_calldata([(0, MANAGERS[0], NEW_MANAGERS[0])]) + with reverts("MANAGER_ALREADY_HAS_ROLE"): + change_node_operator_managers_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script( + owner, + change_node_operator_managers_factory, + node_operators_registry, + acl, +): + "Must create correct EVMScript if all requirements are met" + + input_params = [ + (0, MANAGERS[0], NEW_MANAGERS[0]), + (1, MANAGERS[1], NEW_MANAGERS[1]), + ] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = change_node_operator_managers_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + + scripts = [] + for input_param in input_params: + scripts.append( + ( + acl.address, + acl.revokePermission.encode_input( + input_param[1], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + ), + ) + ) + scripts.append( + ( + acl.address, + acl.grantPermissionP.encode_input( + input_param[2], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, input_param[0])]), + ), + ) + ) + expected_evm_script = encode_call_script(scripts) + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(change_node_operator_managers_factory): + "Must decode EVMScript call data correctly" + input_params = [ + (0, MANAGERS[0], NEW_MANAGERS[0]), + (1, MANAGERS[1], NEW_MANAGERS[1]), + ] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert change_node_operator_managers_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_deactivate_node_operators.py b/tests/evm_script_factories/test_deactivate_node_operators.py new file mode 100644 index 00000000..c0f77d14 --- /dev/null +++ b/tests/evm_script_factories/test_deactivate_node_operators.py @@ -0,0 +1,185 @@ +import pytest +from eth_abi import encode +from brownie import reverts, DeactivateNodeOperators, web3 + +from utils.evm_script import encode_call_script +from utils.permission_parameters import Op, Param, encode_permission_params + +MANAGERS = [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", +] + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,address)[]"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def deactivate_node_operators_factory(owner, node_operators_registry, acl, voting): + acl.grantPermission( + voting, + node_operators_registry, + web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE").hex(), + {"from": voting}, + ) + for id, manager in enumerate(MANAGERS): + acl.grantPermissionP( + manager, + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, id)]), + {"from": voting}, + ) + return DeactivateNodeOperators.deploy(owner, node_operators_registry, acl, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, acl, deactivate_node_operators_factory): + "Must deploy contract with correct data" + assert deactivate_node_operators_factory.trustedCaller() == owner + assert deactivate_node_operators_factory.nodeOperatorsRegistry() == node_operators_registry + assert deactivate_node_operators_factory.acl() == acl + + +def test_create_evm_script_called_by_stranger(stranger, deactivate_node_operators_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + deactivate_node_operators_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_empty_calldata(owner, deactivate_node_operators_factory): + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([]) + deactivate_node_operators_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_non_sorted_calldata(owner, deactivate_node_operators_factory): + "Must revert with message 'NODE_OPERATORS_IS_NOT_SORTED' when operator ids isn't sorted" + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(1, MANAGERS[1]), (0, MANAGERS[0])]) + deactivate_node_operators_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(0, MANAGERS[0]), (0, MANAGERS[0])]) + deactivate_node_operators_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_operator_id_out_of_range(owner, deactivate_node_operators_factory, node_operators_registry): + "Must revert with message 'NODE_OPERATOR_INDEX_OUT_OF_RANGE' when operator id gt operators count" + + with reverts("NODE_OPERATOR_INDEX_OUT_OF_RANGE"): + node_operators_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata( + [ + ( + node_operators_count, + "0x0000000000000000000000000000000000000000", + ) + ] + ) + deactivate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_node_operator_invalid_state(owner, deactivate_node_operators_factory, node_operators_registry, voting): + "Must revert with message 'WRONG_OPERATOR_ACTIVE_STATE' when operator already active" + + node_operators_registry.deactivateNodeOperator(0, {"from": voting}) + + with reverts("WRONG_OPERATOR_ACTIVE_STATE"): + CALLDATA = create_calldata([(0, MANAGERS[0])]) + deactivate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_has_no_role(owner, deactivate_node_operators_factory, node_operators_registry, acl, voting): + "Must revert with message 'MANAGER_HAS_NO_ROLE' when manager has no MANAGE_SIGNING_KEYS role" + + CALLDATA = create_calldata([(2, MANAGERS[0])]) + with reverts("MANAGER_HAS_NO_ROLE"): + deactivate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_has_another_role_operator( + owner, deactivate_node_operators_factory, node_operators_registry, acl, voting +): + "Must revert with message 'MANAGER_HAS_NO_ROLE' when manager has MANAGE_SIGNING_KEYS role with wrong param operator" + + manager = "0x0000000000000000000000000000000000000001" + operator = 2 + + acl.grantPermissionP( + manager, + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.NEQ, operator)]), + {"from": voting}, + ) + + CALLDATA = create_calldata([(operator, manager)]) + with reverts("MANAGER_HAS_NO_ROLE"): + deactivate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_manager_has_role_for_another_operator( + owner, deactivate_node_operators_factory, node_operators_registry, acl, voting +): + "Must revert with message 'MANAGER_HAS_NO_ROLE' when manager has MANAGE_SIGNING_KEYS role with wrong param operator" + + manager = "0x0000000000000000000000000000000000000001" + operator = 2 + + acl.grantPermissionP( + manager, + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + encode_permission_params([Param(0, Op.EQ, operator + 1)]), + {"from": voting}, + ) + + CALLDATA = create_calldata([(operator, manager)]) + with reverts("MANAGER_HAS_NO_ROLE"): + deactivate_node_operators_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script(owner, deactivate_node_operators_factory, node_operators_registry, acl): + "Must create correct EVMScript if all requirements are met" + input_params = [(id, manager) for id, manager in enumerate(MANAGERS)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = deactivate_node_operators_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + scripts = [] + for input_param in input_params: + scripts.append( + ( + node_operators_registry.address, + node_operators_registry.deactivateNodeOperator.encode_input(input_param[0]), + ) + ) + scripts.append( + ( + acl.address, + acl.revokePermission.encode_input( + input_param[1], + node_operators_registry, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + ), + ) + ) + expected_evm_script = encode_call_script(scripts) + + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(node_operators_registry, deactivate_node_operators_factory): + "Must decode EVMScript call data correctly" + input_params = [(id, manager) for id, manager in enumerate(MANAGERS)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert deactivate_node_operators_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_increase_node_operator_staking_limit.py b/tests/evm_script_factories/test_increase_node_operator_staking_limit.py index 801b9f3c..8f1d3932 100644 --- a/tests/evm_script_factories/test_increase_node_operator_staking_limit.py +++ b/tests/evm_script_factories/test_increase_node_operator_staking_limit.py @@ -1,11 +1,11 @@ from brownie import reverts -from eth_abi import encode_single +from eth_abi import encode from utils.evm_script import encode_call_script NODE_OPERATOR_ID = 1 STAKING_LIMIT = 350 -CALL_DATA = encode_single("(uint256,uint256)", [NODE_OPERATOR_ID, STAKING_LIMIT]) +CALLDATA = encode(["uint256", "uint256"], [NODE_OPERATOR_ID, STAKING_LIMIT]) def test_deploy(owner, node_operators_registry, IncreaseNodeOperatorStakingLimit): @@ -14,13 +14,11 @@ def test_deploy(owner, node_operators_registry, IncreaseNodeOperatorStakingLimit assert contract.nodeOperatorsRegistry() == node_operators_registry -def test_create_evm_script_different_reward_address( - owner, stranger, increase_node_operator_staking_limit -): +def test_create_evm_script_different_reward_address(owner, stranger, increase_node_operator_staking_limit): "Must revert with message 'CALLER_IS_NOT_NODE_OPERATOR'" "if creator address is not equal to rewardAddress of node operator" with reverts("CALLER_IS_NOT_NODE_OPERATOR"): - increase_node_operator_staking_limit.createEVMScript(stranger, CALL_DATA) + increase_node_operator_staking_limit.createEVMScript(stranger, CALLDATA) def test_create_evm_script_node_operator_disabled( @@ -30,19 +28,19 @@ def test_create_evm_script_node_operator_disabled( "if node operator with rewardAddress equals to the creator is disabled" node_operators_registry_stub.setActive(False) with reverts("NODE_OPERATOR_DISABLED"): - increase_node_operator_staking_limit.createEVMScript(node_operator, CALL_DATA) + increase_node_operator_staking_limit.createEVMScript(node_operator, CALLDATA) def test_create_evm_script_new_staking_limit_too_low( node_operator, node_operators_registry_stub, increase_node_operator_staking_limit ): "Must revert with message: 'STAKING_LIMIT_TOO_LOW' if new staking limit" - "is less or equal than current stakin limit of node operator" + "is less or equal than current staking limit of node operator" node_operators_registry_stub.setStakingLimit(370) assert node_operators_registry_stub.stakingLimit() == 370 with reverts("STAKING_LIMIT_TOO_LOW"): - increase_node_operator_staking_limit.createEVMScript(node_operator, CALL_DATA) + increase_node_operator_staking_limit.createEVMScript(node_operator, CALLDATA) def test_create_evm_script_new_staking_limit_less_than_total_signing_keys( @@ -55,23 +53,17 @@ def test_create_evm_script_new_staking_limit_less_than_total_signing_keys( assert node_operators_registry_stub.totalSigningKeys() == 300 with reverts("NOT_ENOUGH_SIGNING_KEYS"): - increase_node_operator_staking_limit.createEVMScript(node_operator, CALL_DATA) + increase_node_operator_staking_limit.createEVMScript(node_operator, CALLDATA) -def test_create_evm_script( - node_operator, node_operators_registry_stub, increase_node_operator_staking_limit -): +def test_create_evm_script(node_operator, node_operators_registry_stub, increase_node_operator_staking_limit): "Must create correct EVMScript if all requirements are met" - evm_script = increase_node_operator_staking_limit.createEVMScript( - node_operator, CALL_DATA - ) + evm_script = increase_node_operator_staking_limit.createEVMScript(node_operator, CALLDATA) expected_evm_script = encode_call_script( [ ( node_operators_registry_stub.address, - node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input( - NODE_OPERATOR_ID, STAKING_LIMIT - ), + node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input(NODE_OPERATOR_ID, STAKING_LIMIT), ) ] ) @@ -81,7 +73,7 @@ def test_create_evm_script( def test_decode_evm_script_call_data(increase_node_operator_staking_limit): "Must decode EVMScript call data correctly" - assert increase_node_operator_staking_limit.decodeEVMScriptCallData(CALL_DATA) == [ + assert increase_node_operator_staking_limit.decodeEVMScriptCallData(CALLDATA) == [ NODE_OPERATOR_ID, STAKING_LIMIT, ] diff --git a/tests/evm_script_factories/test_increase_vetted_validators_limits.py b/tests/evm_script_factories/test_increase_vetted_validators_limits.py new file mode 100644 index 00000000..26cddead --- /dev/null +++ b/tests/evm_script_factories/test_increase_vetted_validators_limits.py @@ -0,0 +1,152 @@ +import pytest +from eth_abi import encode +from brownie import reverts, IncreaseVettedValidatorsLimit + +from utils.permission_parameters import Op, Param, encode_permission_params +from utils.evm_script import encode_call_script + + +signing_keys = { + "pubkeys": [ + "8bb1db218877a42047b953bdc32573445a78d93383ef5fd08f79c066d4781961db4f5ab5a7cc0cf1e4cbcc23fd17f9d7", + "884b147305bcd9fce3a1cc12e8f893c6356c1780688286277656e1ba724a3fde49262c98503141c0925b344a8ccea9ca", + "952ff22cf4a5f9708d536acb2170f83c137301515df5829adc28c265373487937cc45e8f91743caba0b9ebd02b3b664f", + ], + "signatures": [ + "ad17ef7cdf0c4917aaebc067a785b049d417dda5d4dd66395b21bbd50781d51e28ee750183eca3d32e1f57b324049a06135ad07d1aa243368bca9974e25233f050e0d6454894739f87faace698b90ea65ee4baba2758772e09fec4f1d8d35660", + "9794e7871dc766c2139f9476234bc29784e13b51e859445044d2a5a9df8bc072d9c51c51ee69490ce37bdfc7cf899af2166b0710d620a87398d5ec7da06c9f7eb27f1d729973efd60052dbd4cb7f43ff6b141af4d0a0a980b60f663f39bf7844", + "90111fb6944ff8b56eb0858c1deb91f41c8c631573f4c821663d7079e5e78903d67fa1c4a4ed358378f16a2b7ec524c5196b1a1eae35b01dca1df74535f45d6bd1960164a41425b2a289d4bb5c837049acf5871a0ed23598df42f6234276f6e2", + ], +} + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,uint256)"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def increase_vetted_validators_limit_factory(owner, node_operators_registry): + return IncreaseVettedValidatorsLimit.deploy(node_operators_registry, {"from": owner}) + + +def test_deploy(node_operators_registry, increase_vetted_validators_limit_factory): + "Must deploy contract with correct data" + assert increase_vetted_validators_limit_factory.nodeOperatorsRegistry() == node_operators_registry + + +def test_create_evm_script_called_by_stranger(stranger, increase_vetted_validators_limit_factory): + "Must revert with message 'CALLER_IS_NOT_NODE_OPERATOR_OR_MANAGER' if creator isn't node operators reward address or manager" + EVM_SCRIPT_CALLDATA = create_calldata((0, 1)) + with reverts("CALLER_IS_NOT_NODE_OPERATOR_OR_MANAGER"): + increase_vetted_validators_limit_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_create_evm_script_called_when_operator_disabled( + increase_vetted_validators_limit_factory, agent, node_operators_registry +): + "Must revert with message 'NODE_OPERATOR_DISABLED' if called when operator disabled" + + node_operators_registry.deactivateNodeOperator(0, {"from": agent}) + no = node_operators_registry.getNodeOperator(0, True) + + EVM_SCRIPT_CALLDATA = create_calldata((0, 1)) + + with reverts("NODE_OPERATOR_DISABLED"): + increase_vetted_validators_limit_factory.createEVMScript(no["rewardAddress"], EVM_SCRIPT_CALLDATA) + + +def test_revert_on_not_enough_signing_keys(increase_vetted_validators_limit_factory, node_operators_registry): + "Must revert with message 'NOT_ENOUGH_SIGNING_KEYS' when node operator has not enough keys" + no = node_operators_registry.getNodeOperator(0, True) + + with reverts("NOT_ENOUGH_SIGNING_KEYS"): + CALLDATA = create_calldata((0, 100000)) + increase_vetted_validators_limit_factory.createEVMScript(no["rewardAddress"], CALLDATA) + + +def test_revert_on_new_value_is_too_low(increase_vetted_validators_limit_factory, node_operators_registry): + "Must revert with message 'STAKING_LIMIT_TOO_LOW' when new value is too low" + no = node_operators_registry.getNodeOperator(0, True) + + with reverts("STAKING_LIMIT_TOO_LOW"): + CALLDATA = create_calldata((0, 0)) + increase_vetted_validators_limit_factory.createEVMScript(no["rewardAddress"], CALLDATA) + + +def test_create_evm_script_from_reward_address( + increase_vetted_validators_limit_factory, + node_operators_registry, +): + "Must create correct EVMScript if all requirements are met" + + no = node_operators_registry.getNodeOperator(0, True) + node_operators_registry.addSigningKeysOperatorBH( + 0, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": no["rewardAddress"]}, + ) + input_params = (0, no["totalVettedValidators"] + len(signing_keys["pubkeys"])) + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = increase_vetted_validators_limit_factory.createEVMScript(no["rewardAddress"], EVM_SCRIPT_CALLDATA) + expected_evm_script = encode_call_script( + [ + ( + node_operators_registry.address, + node_operators_registry.setNodeOperatorStakingLimit.encode_input(input_params[0], input_params[1]), + ) + ] + ) + assert evm_script == expected_evm_script + + +def test_create_evm_script_from_manager(increase_vetted_validators_limit_factory, node_operators_registry, acl, voting): + "Must create correct EVMScript if all requirements are met" + no_manager = "0x1f9090aae28b8a3dceadf281b0f12828e676c327" + + no = node_operators_registry.getNodeOperator(0, True) + + acl.grantPermissionP( + no_manager, + node_operators_registry, + node_operators_registry.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, 0)]), + {"from": voting}, + ) + + node_operators_registry.addSigningKeysOperatorBH( + 0, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": no_manager}, + ) + input_params = (0, no["totalVettedValidators"] + len(signing_keys["pubkeys"])) + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = increase_vetted_validators_limit_factory.createEVMScript(no_manager, EVM_SCRIPT_CALLDATA) + expected_evm_script = encode_call_script( + [ + ( + node_operators_registry.address, + node_operators_registry.setNodeOperatorStakingLimit.encode_input(input_params[0], input_params[1]), + ) + ] + ) + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(node_operators_registry, increase_vetted_validators_limit_factory): + "Must decode EVMScript call data correctly" + input_params = (0, 1) + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert increase_vetted_validators_limit_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_remove_allowed_recipient.py b/tests/evm_script_factories/test_remove_allowed_recipient.py new file mode 100644 index 00000000..15532043 --- /dev/null +++ b/tests/evm_script_factories/test_remove_allowed_recipient.py @@ -0,0 +1,89 @@ +from brownie import ZERO_ADDRESS, reverts +from utils.evm_script import encode_calldata, encode_call_script + + +def test_deploy(owner, RemoveAllowedRecipient, allowed_recipients_registry): + "Must deploy contract with correct data" + (registry, _, _, _, _, _) = allowed_recipients_registry + contract = owner.deploy(RemoveAllowedRecipient, owner, registry) + + assert contract.trustedCaller() == owner + assert contract.allowedRecipientsRegistry() == registry + + +def test_deploy_zero_trusted_caller(owner, RemoveAllowedRecipient, allowed_recipients_registry): + "Must revert deploying a contract with zero trusted caller" + (registry, _, _, _, _, _) = allowed_recipients_registry + + with reverts("TRUSTED_CALLER_IS_ZERO_ADDRESS"): + owner.deploy(RemoveAllowedRecipient, ZERO_ADDRESS, registry) + + +def test_deploy_zero_allowed_recipient_registry(owner, RemoveAllowedRecipient): + "Must deploy contract with zero allowed recipient registry" + contract = owner.deploy(RemoveAllowedRecipient, owner, ZERO_ADDRESS) + assert contract.allowedRecipientsRegistry() == ZERO_ADDRESS + + +def test_create_evm_script_is_permissionless(owner, stranger, remove_allowed_recipients, allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + registry.addRecipient(stranger, "Stranger", {"from": add_recipient_role_holder}) + call_data = create_calldata(stranger.address) + remove_allowed_recipients.createEVMScript(owner, call_data, {"from": stranger}) + + +def test_decode_evm_script_calldata_is_permissionless(stranger, remove_allowed_recipients): + call_data = create_calldata(stranger.address) + remove_allowed_recipients.decodeEVMScriptCallData(call_data, {"from": stranger}) + + +def test_only_trusted_caller_can_be_creator(owner, stranger, remove_allowed_recipients, allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + registry.addRecipient(stranger, "Stranger", {"from": add_recipient_role_holder}) + call_data = create_calldata(stranger.address) + + with reverts("CALLER_IS_FORBIDDEN"): + remove_allowed_recipients.createEVMScript(stranger, call_data, {"from": owner}) + + remove_allowed_recipients.createEVMScript(owner, call_data, {"from": owner}) + + +def test_revert_create_evm_script_with_empty_calldata(owner, remove_allowed_recipients): + with reverts(): + remove_allowed_recipients.createEVMScript(owner, "0x", {"from": owner}) + + +def test_revert_recipient_not_found(owner, stranger, remove_allowed_recipients): + call_data = create_calldata(stranger.address) + + with reverts("ALLOWED_RECIPIENT_NOT_FOUND"): + remove_allowed_recipients.createEVMScript(owner, call_data) + + +def test_create_evm_script_correctly(owner, stranger, remove_allowed_recipients, allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + registry.addRecipient(stranger, "Stranger", {"from": add_recipient_role_holder}) + call_data = create_calldata(stranger.address) + evm_script = remove_allowed_recipients.createEVMScript(owner, call_data) + (registry, _, _, _, _, _) = allowed_recipients_registry + expected_evm_script = encode_call_script( + [ + ( + registry.address, + registry.removeRecipient.encode_input(stranger), + ) + ] + ) + + assert evm_script == expected_evm_script + + +def test_decode_evm_script_calldata_correctly(owner, remove_allowed_recipients): + call_data = create_calldata(owner.address) + + address = remove_allowed_recipients.decodeEVMScriptCallData(call_data) + assert address == owner.address + + +def create_calldata(recipient): + return encode_calldata(["address"], [recipient]) diff --git a/tests/evm_script_factories/test_remove_reward_program.py b/tests/evm_script_factories/test_remove_reward_program.py index b8576119..0c7003de 100644 --- a/tests/evm_script_factories/test_remove_reward_program.py +++ b/tests/evm_script_factories/test_remove_reward_program.py @@ -1,10 +1,10 @@ -from eth_abi import encode_single +from eth_abi import encode from brownie import reverts from utils.evm_script import encode_call_script REWARD_PROGRAM_ADDRESS = "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF" -EVM_SCRIPT_CALL_DATA = "0x" + encode_single("(address)", [REWARD_PROGRAM_ADDRESS]).hex() +EVM_SCRIPT_CALLDATA = "0x" + encode(["address"], [REWARD_PROGRAM_ADDRESS]).hex() def test_deploy(owner, reward_programs_registry, RemoveRewardProgram): @@ -17,7 +17,7 @@ def test_deploy(owner, reward_programs_registry, RemoveRewardProgram): def test_create_evm_script_called_by_stranger(stranger, remove_reward_program): "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" with reverts("CALLER_IS_FORBIDDEN"): - remove_reward_program.createEVMScript(stranger, EVM_SCRIPT_CALL_DATA) + remove_reward_program.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) def test_create_evm_script_reward_program_already_added( @@ -27,25 +27,19 @@ def test_create_evm_script_reward_program_already_added( with reverts("REWARD_PROGRAM_NOT_FOUND"): remove_reward_program.createEVMScript( owner, - EVM_SCRIPT_CALL_DATA, + EVM_SCRIPT_CALLDATA, ) -def test_create_evm_script( - owner, remove_reward_program, reward_programs_registry, evm_script_executor_stub -): +def test_create_evm_script(owner, remove_reward_program, reward_programs_registry, evm_script_executor_stub): "Must create correct EVMScript if all requirements are met" - reward_programs_registry.addRewardProgram( - REWARD_PROGRAM_ADDRESS, "", {"from": evm_script_executor_stub} - ) - evm_script = remove_reward_program.createEVMScript(owner, EVM_SCRIPT_CALL_DATA) + reward_programs_registry.addRewardProgram(REWARD_PROGRAM_ADDRESS, "", {"from": evm_script_executor_stub}) + evm_script = remove_reward_program.createEVMScript(owner, EVM_SCRIPT_CALLDATA) expected_evm_script = encode_call_script( [ ( reward_programs_registry.address, - reward_programs_registry.removeRewardProgram.encode_input( - REWARD_PROGRAM_ADDRESS - ), + reward_programs_registry.removeRewardProgram.encode_input(REWARD_PROGRAM_ADDRESS), ) ] ) @@ -55,7 +49,4 @@ def test_create_evm_script( def test_decode_evm_script_call_data(remove_reward_program): "Must decode EVMScript call data correctly" - assert ( - remove_reward_program.decodeEVMScriptCallData(EVM_SCRIPT_CALL_DATA) - == REWARD_PROGRAM_ADDRESS - ) + assert remove_reward_program.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == REWARD_PROGRAM_ADDRESS diff --git a/tests/evm_script_factories/test_set_node_operator_names.py b/tests/evm_script_factories/test_set_node_operator_names.py new file mode 100644 index 00000000..71b67915 --- /dev/null +++ b/tests/evm_script_factories/test_set_node_operator_names.py @@ -0,0 +1,114 @@ +import pytest +from eth_abi import encode +from brownie import reverts, SetNodeOperatorNames + +from utils.evm_script import encode_call_script + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,string)[]"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def set_node_operator_name_factory(owner, node_operators_registry): + print(node_operators_registry.getNodeOperatorsCount()) + return SetNodeOperatorNames.deploy(owner, node_operators_registry, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, set_node_operator_name_factory): + "Must deploy contract with correct data" + assert set_node_operator_name_factory.trustedCaller() == owner + assert set_node_operator_name_factory.nodeOperatorsRegistry() == node_operators_registry + + +def test_create_evm_script_called_by_stranger(stranger, set_node_operator_name_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + set_node_operator_name_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_empty_calldata(owner, set_node_operator_name_factory): + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([]) + set_node_operator_name_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_non_sorted_calldata(owner, set_node_operator_name_factory): + "Must revert with message 'NODE_OPERATORS_IS_NOT_SORTED' when operator ids isn't sorted" + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + print(12333) + NON_SORTED_CALLDATA = create_calldata([(1, "New Name"), (0, "New Name")]) + set_node_operator_name_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(0, "New Name"), (0, "New Name")]) + set_node_operator_name_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_operator_id_out_of_range(owner, set_node_operator_name_factory, node_operators_registry): + "Must revert with message 'NODE_OPERATOR_INDEX_OUT_OF_RANGE' when operator id gt operators count" + + with reverts("NODE_OPERATOR_INDEX_OUT_OF_RANGE"): + node_operators_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata([(node_operators_count, "New Name")]) + set_node_operator_name_factory.createEVMScript(owner, CALLDATA) + + +def test_name_invalid_length(owner, set_node_operator_name_factory, node_operators_registry): + "Must revert with message 'WRONG_NAME_LENGTH' when name length eq to 0 or gt max length" + + with reverts("WRONG_NAME_LENGTH"): + CALLDATA = create_calldata([(0, "")]) + set_node_operator_name_factory.createEVMScript(owner, CALLDATA) + + with reverts("WRONG_NAME_LENGTH"): + max_length = node_operators_registry.MAX_NODE_OPERATOR_NAME_LENGTH() + CALLDATA = create_calldata([(0, "x" * (max_length + 1))]) + set_node_operator_name_factory.createEVMScript(owner, CALLDATA) + + +def test_same_name(owner, set_node_operator_name_factory, node_operators_registry): + "Must revert with message 'SAME_NAME' when name is the same" + + with reverts("SAME_NAME"): + node_operator = node_operators_registry.getNodeOperator(0, True) + CALLDATA = create_calldata([(0, node_operator["name"])]) + set_node_operator_name_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script( + owner, + set_node_operator_name_factory, + node_operators_registry, +): + "Must create correct EVMScript if all requirements are met" + input_params = [(0, "New name"), (1, "Another Name")] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = set_node_operator_name_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + expected_evm_script = encode_call_script( + [ + ( + node_operators_registry.address, + node_operators_registry.setNodeOperatorName.encode_input(input_param[0], input_param[1]), + ) + for input_param in input_params + ] + ) + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(node_operators_registry, set_node_operator_name_factory): + "Must decode EVMScript call data correctly" + input_params = [(0, "New name"), (1, "Another Name")] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert set_node_operator_name_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_set_node_operator_reward_addresses.py b/tests/evm_script_factories/test_set_node_operator_reward_addresses.py new file mode 100644 index 00000000..689447d7 --- /dev/null +++ b/tests/evm_script_factories/test_set_node_operator_reward_addresses.py @@ -0,0 +1,123 @@ +import pytest +from eth_abi import encode +from brownie import reverts, SetNodeOperatorRewardAddresses, ZERO_ADDRESS + +from utils.evm_script import encode_call_script + +NEW_REWARD_ADDRESSES = [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", +] + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,address)[]"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def set_node_operator_reward_addresses_factory(owner, node_operators_registry, steth): + return SetNodeOperatorRewardAddresses.deploy(owner, node_operators_registry, steth, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, set_node_operator_reward_addresses_factory): + "Must deploy contract with correct data" + assert set_node_operator_reward_addresses_factory.trustedCaller() == owner + assert set_node_operator_reward_addresses_factory.nodeOperatorsRegistry() == node_operators_registry + + +def test_create_evm_script_called_by_stranger(stranger, set_node_operator_reward_addresses_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + set_node_operator_reward_addresses_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_empty_calldata(owner, set_node_operator_reward_addresses_factory): + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([]) + set_node_operator_reward_addresses_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_non_sorted_calldata(owner, set_node_operator_reward_addresses_factory): + "Must revert with message 'NODE_OPERATORS_IS_NOT_SORTED' when operator ids isn't sorted" + + input_params = [(id, new_reward_address) for id, new_reward_address in enumerate(NEW_REWARD_ADDRESSES)] + print(input_params) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([input_params[1], input_params[0]]) + set_node_operator_reward_addresses_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([input_params[0], input_params[0]]) + set_node_operator_reward_addresses_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_operator_id_out_of_range(owner, set_node_operator_reward_addresses_factory, node_operators_registry): + "Must revert with message 'NODE_OPERATOR_INDEX_OUT_OF_RANGE' when operator id gt operators count" + + with reverts("NODE_OPERATOR_INDEX_OUT_OF_RANGE"): + node_operators_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata([(node_operators_count, NEW_REWARD_ADDRESSES[0])]) + set_node_operator_reward_addresses_factory.createEVMScript(owner, CALLDATA) + + +def test_same_reward_address(owner, set_node_operator_reward_addresses_factory, node_operators_registry): + "Must revert with message 'SAME_REWARD_ADDRESS' when address is the same" + + with reverts("SAME_REWARD_ADDRESS"): + node_operator = node_operators_registry.getNodeOperator(0, True) + CALLDATA = create_calldata([(0, node_operator["rewardAddress"])]) + set_node_operator_reward_addresses_factory.createEVMScript(owner, CALLDATA) + + +def test_zero_reward_address(owner, set_node_operator_reward_addresses_factory): + "Must revert with message 'ZERO_REWARD_ADDRESS' when address is zero address" + + with reverts("ZERO_REWARD_ADDRESS"): + CALLDATA = create_calldata([(0, ZERO_ADDRESS)]) + set_node_operator_reward_addresses_factory.createEVMScript(owner, CALLDATA) + + +def test_lido_as_reward_address(owner, set_node_operator_reward_addresses_factory, steth): + "Must revert with message 'ZERO_REWARD_ADDRESS' when address is lido address" + + with reverts("LIDO_REWARD_ADDRESS"): + CALLDATA = create_calldata([(0, steth.address)]) + set_node_operator_reward_addresses_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script( + owner, + set_node_operator_reward_addresses_factory, + node_operators_registry, +): + "Must create correct EVMScript if all requirements are met" + input_params = [(id, new_reward_address) for id, new_reward_address in enumerate(NEW_REWARD_ADDRESSES)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = set_node_operator_reward_addresses_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + expected_evm_script = encode_call_script( + [ + ( + node_operators_registry.address, + node_operators_registry.setNodeOperatorRewardAddress.encode_input(input_param[0], input_param[1]), + ) + for input_param in input_params + ] + ) + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(node_operators_registry, set_node_operator_reward_addresses_factory): + "Must decode EVMScript call data correctly" + input_params = [(id, new_reward_address) for id, new_reward_address in enumerate(NEW_REWARD_ADDRESSES)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert set_node_operator_reward_addresses_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_set_vetted_validators_limits.py b/tests/evm_script_factories/test_set_vetted_validators_limits.py new file mode 100644 index 00000000..eb34eb99 --- /dev/null +++ b/tests/evm_script_factories/test_set_vetted_validators_limits.py @@ -0,0 +1,119 @@ +import pytest +from eth_abi import encode +from brownie import reverts, SetVettedValidatorsLimits, web3 + +from utils.evm_script import encode_call_script + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,uint256)[]"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def set_vetted_validators_limits_factory(owner, node_operators_registry): + return SetVettedValidatorsLimits.deploy(owner, node_operators_registry, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, set_vetted_validators_limits_factory): + "Must deploy contract with correct data" + assert set_vetted_validators_limits_factory.trustedCaller() == owner + assert set_vetted_validators_limits_factory.nodeOperatorsRegistry() == node_operators_registry + + +def test_create_evm_script_called_by_stranger(stranger, set_vetted_validators_limits_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + set_vetted_validators_limits_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_empty_calldata(owner, set_vetted_validators_limits_factory): + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([]) + set_vetted_validators_limits_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_non_sorted_calldata(owner, set_vetted_validators_limits_factory): + "Must revert with message 'NODE_OPERATORS_IS_NOT_SORTED' when operator ids isn't sorted" + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(1, 1), (0, 2)]) + set_vetted_validators_limits_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(0, 1), (0, 2)]) + set_vetted_validators_limits_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_non_active_operator_calldata( + owner, set_vetted_validators_limits_factory, node_operators_registry, voting, acl +): + "Must revert with message 'NODE_OPERATOR_IS_NOT_ACTIVE' when operator isn't active" + acl.grantPermission( + voting, + node_operators_registry, + web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE").hex(), + {"from": voting}, + ) + + input_params = [(0, 1), (1, 1)] + node_operators_registry.deactivateNodeOperator(0, {"from": voting}) + + with reverts("NODE_OPERATOR_IS_NOT_ACTIVE"): + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + set_vetted_validators_limits_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + + +def test_operator_id_out_of_range(owner, set_vetted_validators_limits_factory, node_operators_registry): + "Must revert with message 'NODE_OPERATOR_INDEX_OUT_OF_RANGE' when operator id gt operators count" + + with reverts("NODE_OPERATOR_INDEX_OUT_OF_RANGE"): + node_operators_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata([(node_operators_count, 1)]) + set_vetted_validators_limits_factory.createEVMScript(owner, CALLDATA) + + +def test_revert_on_not_enough_signing_keys(owner, set_vetted_validators_limits_factory, steth): + "Must revert with message 'NOT_ENOUGH_SIGNING_KEYS' when node operator has not enough keys" + + with reverts("NOT_ENOUGH_SIGNING_KEYS"): + CALLDATA = create_calldata([(0, 100000)]) + set_vetted_validators_limits_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script( + owner, + set_vetted_validators_limits_factory, + node_operators_registry, +): + "Must create correct EVMScript if all requirements are met" + + input_params = [(0, 1), (1, 1)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = set_vetted_validators_limits_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + expected_evm_script = encode_call_script( + [ + ( + node_operators_registry.address, + node_operators_registry.setNodeOperatorStakingLimit.encode_input(input_param[0], input_param[1]), + ) + for input_param in input_params + ] + ) + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(node_operators_registry, set_vetted_validators_limits_factory): + "Must decode EVMScript call data correctly" + input_params = [(0, 1), (1, 1)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert set_vetted_validators_limits_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/evm_script_factories/test_top_up_allowed_recipients.py b/tests/evm_script_factories/test_top_up_allowed_recipients.py new file mode 100644 index 00000000..5947caf7 --- /dev/null +++ b/tests/evm_script_factories/test_top_up_allowed_recipients.py @@ -0,0 +1,321 @@ +from brownie import accounts, reverts, ZERO_ADDRESS + +from utils.evm_script import encode_calldata, encode_call_script + + +def make_call_data(recipients, amounts): + return encode_calldata(["address[]", "uint256[]"], [recipients, amounts]) + + +def test_top_up_factory_initial_state( + allowed_recipients_registry, + accounts, + finance, + ldo, + easy_track, + TopUpAllowedRecipients, +): + (registry, owner, _, _, _, _) = allowed_recipients_registry + + trusted_caller = accounts[4] + + top_up_factory = owner.deploy(TopUpAllowedRecipients, trusted_caller, registry, finance, ldo, easy_track) + + assert top_up_factory.token() == ldo + assert top_up_factory.allowedRecipientsRegistry() == registry + assert top_up_factory.trustedCaller() == trusted_caller + assert top_up_factory.easyTrack() == easy_track + assert top_up_factory.finance() == finance + + +def test_fail_if_zero_trusted_caller( + allowed_recipients_registry, + finance, + ldo, + easy_track, + TopUpAllowedRecipients, +): + (registry, owner, _, _, _, _) = allowed_recipients_registry + + with reverts("TRUSTED_CALLER_IS_ZERO_ADDRESS"): + owner.deploy(TopUpAllowedRecipients, ZERO_ADDRESS, registry, finance, ldo, easy_track) + + +def test_top_up_factory_constructor_zero_argument_addresses_allowed(TopUpAllowedRecipients, owner): + """Check no revert""" + trusted_caller = accounts[4] + owner.deploy( + TopUpAllowedRecipients, + trusted_caller, + ZERO_ADDRESS, + ZERO_ADDRESS, + ZERO_ADDRESS, + ZERO_ADDRESS, + ) + + +def test_fail_create_evm_script_if_not_trusted_caller(top_up_allowed_recipients, stranger): + with reverts("CALLER_IS_FORBIDDEN"): + top_up_allowed_recipients.createEVMScript(stranger, make_call_data([], [])) + + +def test_create_evm_script_is_permissionless(allowed_recipients_registry, stranger, top_up_allowed_recipients): + ( + registry, + owner, + add_recipient_role_holder, + _, + set_limit_role_holder, + _, + ) = allowed_recipients_registry + registry.addRecipient(stranger.address, "Test Recipient", {"from": add_recipient_role_holder}) + registry.setLimitParameters(int(100e18), 12, {"from": set_limit_role_holder}) + call_data = make_call_data([stranger.address], [123]) + trusted_caller = top_up_allowed_recipients.trustedCaller() + top_up_allowed_recipients.createEVMScript(trusted_caller, call_data, {"from": stranger}) + + +def test_decode_evm_script_calldata_is_permissionless(stranger, top_up_allowed_recipients): + call_data = make_call_data([stranger.address], [123]) + top_up_allowed_recipients.decodeEVMScriptCallData(call_data, {"from": stranger}) + + +def test_fail_create_evm_script_if_length_mismatch(top_up_allowed_recipients, accounts): + factory = top_up_allowed_recipients + trusted_caller = top_up_allowed_recipients.trustedCaller() + recipient = accounts[2].address + + with reverts("LENGTH_MISMATCH"): + factory.createEVMScript(trusted_caller, make_call_data([recipient], [])) + + with reverts("LENGTH_MISMATCH"): + factory.createEVMScript(trusted_caller, make_call_data([], [123])) + + +def test_fail_create_evm_script_if_empty_data(top_up_allowed_recipients, accounts): + factory = top_up_allowed_recipients + trusted_caller = top_up_allowed_recipients.trustedCaller() + + with reverts("EMPTY_DATA"): + factory.createEVMScript(trusted_caller, make_call_data([], [])) + + +def test_fail_create_evm_script_if_zero_amount( + allowed_recipients_registry, + TopUpAllowedRecipients, + owner, + finance, + ldo, + easy_track, +): + trusted_caller = owner + recipient = accounts[4].address + + ( + registry, + owner, + add_recipient_role_holder, + _, + set_limit_role_holder, + _, + ) = allowed_recipients_registry + + registry.addRecipient(recipient, "Test Recipient", {"from": add_recipient_role_holder}) + registry.setLimitParameters(int(100e18), 12, {"from": set_limit_role_holder}) + + top_up_factory = owner.deploy(TopUpAllowedRecipients, trusted_caller, registry, finance, ldo, easy_track) + + with reverts("ZERO_AMOUNT"): + top_up_factory.createEVMScript(trusted_caller, make_call_data([recipient], [0])) + + with reverts("ZERO_AMOUNT"): + top_up_factory.createEVMScript(trusted_caller, make_call_data([recipient, recipient], [123, 0])) + + +def test_fail_create_evm_script_if_recipient_not_allowed( + allowed_recipients_registry, + TopUpAllowedRecipients, + owner, + finance, + ldo, + easy_track, + stranger, +): + trusted_caller = owner + recipient = accounts[4].address + + ( + registry, + owner, + add_recipient_role_holder, + _, + set_limit_role_holder, + _, + ) = allowed_recipients_registry + + registry.addRecipient(recipient, "Test Recipient", {"from": add_recipient_role_holder}) + registry.setLimitParameters(int(100e18), 12, {"from": set_limit_role_holder}) + + top_up_factory = owner.deploy(TopUpAllowedRecipients, trusted_caller, registry, finance, ldo, easy_track) + + with reverts("RECIPIENT_NOT_ALLOWED"): + top_up_factory.createEVMScript(trusted_caller, make_call_data([stranger.address], [123])) + + +def test_top_up_factory_evm_script_creation_happy_path( + allowed_recipients_registry, + TopUpAllowedRecipients, + owner, + finance, + ldo, + easy_track, +): + trusted_caller = owner + recipient = accounts[4].address + + ( + registry, + owner, + add_recipient_role_holder, + _, + set_limit_role_holder, + _, + ) = allowed_recipients_registry + + registry.addRecipient(recipient, "Test Recipient", {"from": add_recipient_role_holder}) + registry.setLimitParameters(int(100e18), 12, {"from": set_limit_role_holder}) + + top_up_factory = owner.deploy(TopUpAllowedRecipients, trusted_caller, registry, finance, ldo, easy_track) + + payout = int(1e18) + call_data = make_call_data([recipient], [payout]) + evm_script = top_up_factory.createEVMScript(trusted_caller, call_data) + assert top_up_factory.decodeEVMScriptCallData(call_data) == ([recipient], [payout]) + assert "Easy Track: top up recipient".encode("utf-8").hex() in str(evm_script) + + +def test_top_up_factory_evm_script_creation_multiple_recipients_happy_path( + allowed_recipients_registry, + TopUpAllowedRecipients, + owner, + finance, + ldo, + easy_track, +): + trusted_caller = owner + recipients = [accounts[4].address, accounts[5].address] + + ( + registry, + owner, + add_recipient_role_holder, + _, + set_limit_role_holder, + _, + ) = allowed_recipients_registry + + registry.addRecipient(recipients[0], "Test Recipient 1", {"from": add_recipient_role_holder}) + registry.addRecipient(recipients[1], "Test Recipient 2", {"from": add_recipient_role_holder}) + registry.setLimitParameters(int(100e18), 12, {"from": set_limit_role_holder}) + + top_up_factory = owner.deploy(TopUpAllowedRecipients, trusted_caller, registry, finance, ldo, easy_track) + + payouts = [int(1e18), int(2e18)] + call_data = make_call_data(recipients, payouts) + evm_script = top_up_factory.createEVMScript(trusted_caller, call_data) + assert top_up_factory.decodeEVMScriptCallData(call_data) == (recipients, payouts) + assert "Easy Track: top up recipient".encode("utf-8").hex() in str(evm_script) + + +def test_fail_create_evm_script_if_sum_exceeds_limit( + allowed_recipients_registry, + TopUpAllowedRecipients, + owner, + finance, + ldo, + easy_track, +): + + recipients = [accounts[4].address, accounts[5].address] + payouts = [int(10e18), int(20e18)] + call_data = make_call_data(recipients, payouts) + + ( + registry, + owner, + add_recipient_role_holder, + _, + set_limit_role_holder, + _, + ) = allowed_recipients_registry + + registry.addRecipient(recipients[0], "Test Recipient 1", {"from": add_recipient_role_holder}) + registry.addRecipient(recipients[1], "Test Recipient 2", {"from": add_recipient_role_holder}) + registry.setLimitParameters(int(20e18), 12, {"from": set_limit_role_holder}) + + top_up_factory = owner.deploy(TopUpAllowedRecipients, owner, registry, finance, ldo, easy_track) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + top_up_factory.createEVMScript(owner, call_data) + + +def test_create_evm_script_correctly( + allowed_recipients_registry, + TopUpAllowedRecipients, + owner, + finance, + ldo, + easy_track, +): + + recipients = [accounts[4].address, accounts[5].address] + payouts = [int(1e18), int(2e18)] + totalAmount = int(3e18) + + ( + registry, + owner, + add_recipient_role_holder, + _, + set_limit_role_holder, + _, + ) = allowed_recipients_registry + + registry.addRecipient(recipients[0], "Test Recipient 1", {"from": add_recipient_role_holder}) + registry.addRecipient(recipients[1], "Test Recipient 2", {"from": add_recipient_role_holder}) + registry.setLimitParameters(int(100e18), 12, {"from": set_limit_role_holder}) + + top_up_factory = owner.deploy(TopUpAllowedRecipients, owner, registry, finance, ldo, easy_track) + + call_data = make_call_data(recipients, payouts) + evm_script = top_up_factory.createEVMScript(owner, call_data) + expected_evm_script = encode_call_script( + [ + ( + registry.address, + registry.updateSpentAmount.encode_input(totalAmount), + ), + ( + finance.address, + finance.newImmediatePayment.encode_input( + ldo, recipients[0], payouts[0], "Easy Track: top up recipient" + ), + ), + ( + finance.address, + finance.newImmediatePayment.encode_input( + ldo, recipients[1], payouts[1], "Easy Track: top up recipient" + ), + ), + ] + ) + + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(top_up_allowed_recipients, accounts): + recipient = accounts[4].address + payout = int(1e18) + call_data = make_call_data([recipient], [payout]) + + assert top_up_allowed_recipients.decodeEVMScriptCallData(call_data) == [[recipient], [payout]] diff --git a/tests/evm_script_factories/test_top_up_lego_program.py b/tests/evm_script_factories/test_top_up_lego_program.py index f3b078a9..878b3bb1 100644 --- a/tests/evm_script_factories/test_top_up_lego_program.py +++ b/tests/evm_script_factories/test_top_up_lego_program.py @@ -1,13 +1,18 @@ import pytest +import brownie from brownie import reverts -from eth_abi import encode_single +from eth_abi import encode from utils.evm_script import encode_call_script from utils.lido import addresses +REWARD_AMOUNTS = [10**18, 2 * 10**18] -REWARD_TOKENS = [addresses().ldo, addresses().steth] -REWARD_AMOUNTS = [10 ** 18, 2 * 10 ** 18] + +@pytest.fixture(scope="module") +def reward_token_addresses(): + lido_addresses = addresses(network=brownie.network.show_active()) + return [lido_addresses.ldo, lido_addresses.steth] def test_deploy(owner, finance, lego_program, TopUpLegoProgram): @@ -21,17 +26,15 @@ def test_deploy(owner, finance, lego_program, TopUpLegoProgram): def test_create_evm_script_called_by_stranger(stranger, top_up_lego_program): "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" with reverts("CALLER_IS_FORBIDDEN"): - top_up_lego_program.createEVMScript( - stranger, encode_call_data([], []), {"from": stranger} - ) + top_up_lego_program.createEVMScript(stranger, encode_call_data([], []), {"from": stranger}) -def test_create_evm_script_data_length_mismatch(owner, top_up_lego_program): +def test_create_evm_script_data_length_mismatch(owner, top_up_lego_program, reward_token_addresses): "Must revert with message 'LENGTH_MISMATCH' if rewardTokens and amounts has different lengths" with reverts("LENGTH_MISMATCH"): top_up_lego_program.createEVMScript( owner, - encode_call_data(REWARD_TOKENS, [1 ** 18]), + encode_call_data(reward_token_addresses, [1**18]), ) @@ -41,28 +44,24 @@ def test_create_evm_script_empty_data(owner, top_up_lego_program): top_up_lego_program.createEVMScript(owner, encode_call_data([], [])) -def test_create_evm_script_zero_amount(owner, top_up_lego_program): +def test_create_evm_script_zero_amount(owner, top_up_lego_program, reward_token_addresses): "Must revert with message 'ZERO_AMOUNT' if some value in amounts has zero value" - amounts = [1 ** 18, 0] + amounts = [1**18, 0] with reverts("ZERO_AMOUNT"): - top_up_lego_program.createEVMScript( - owner, encode_call_data(REWARD_TOKENS, amounts) - ) + top_up_lego_program.createEVMScript(owner, encode_call_data(reward_token_addresses, amounts)) -def test_create_evm_script(owner, lego_program, top_up_lego_program, finance, ldo): +def test_create_evm_script(owner, lego_program, top_up_lego_program, finance, ldo, reward_token_addresses): "Must create correct EVMScript if all requirements are met" - evm_script = top_up_lego_program.createEVMScript( - owner, encode_call_data(REWARD_TOKENS, REWARD_AMOUNTS) - ) + evm_script = top_up_lego_program.createEVMScript(owner, encode_call_data(reward_token_addresses, REWARD_AMOUNTS)) expected_evm_script = encode_call_script( [ ( finance.address, finance.newImmediatePayment.encode_input( - REWARD_TOKENS[0], + reward_token_addresses[0], lego_program, REWARD_AMOUNTS[0], "Lego Program Transfer", @@ -71,7 +70,7 @@ def test_create_evm_script(owner, lego_program, top_up_lego_program, finance, ld ( finance.address, finance.newImmediatePayment.encode_input( - REWARD_TOKENS[1], + reward_token_addresses[1], lego_program, REWARD_AMOUNTS[1], "Lego Program Transfer", @@ -83,12 +82,13 @@ def test_create_evm_script(owner, lego_program, top_up_lego_program, finance, ld assert evm_script == expected_evm_script -def test_decode_evm_script_call_data(top_up_lego_program): +def test_decode_evm_script_call_data(top_up_lego_program, reward_token_addresses): "Must decode EVMScript call data correctly" - assert top_up_lego_program.decodeEVMScriptCallData( - encode_call_data(REWARD_TOKENS, REWARD_AMOUNTS) - ) == (REWARD_TOKENS, REWARD_AMOUNTS) + assert top_up_lego_program.decodeEVMScriptCallData(encode_call_data(reward_token_addresses, REWARD_AMOUNTS)) == ( + reward_token_addresses, + REWARD_AMOUNTS, + ) def encode_call_data(addresses, amounts): - return "0x" + encode_single("(address[],uint256[])", [addresses, amounts]).hex() + return "0x" + encode(["address[]", "uint256[]"], [addresses, amounts]).hex() diff --git a/tests/evm_script_factories/test_top_up_reward_programs.py b/tests/evm_script_factories/test_top_up_reward_programs.py index cbd0f5e2..274289ae 100644 --- a/tests/evm_script_factories/test_top_up_reward_programs.py +++ b/tests/evm_script_factories/test_top_up_reward_programs.py @@ -1,5 +1,5 @@ -from eth_abi import encode_single from brownie import reverts +from eth_abi import encode from utils.evm_script import encode_call_script @@ -7,14 +7,12 @@ "0xffffFfFffffFfffffFFfFfFFfFffFfFfFFFfFfaA", "0xfFFFfFfFfffFffFfFfFFfFFfffFfFfFffffffFbb", ] -REWARD_PROGRAM_AMOUNTS = [10 ** 18, 2 * 10 ** 18] +REWARD_PROGRAM_AMOUNTS = [10**18, 2 * 10**18] def test_deploy(owner, reward_programs_registry, finance, ldo, TopUpRewardPrograms): "Must deploy contract with correct data" - contract = owner.deploy( - TopUpRewardPrograms, owner, reward_programs_registry, finance, ldo - ) + contract = owner.deploy(TopUpRewardPrograms, owner, reward_programs_registry, finance, ldo) assert contract.trustedCaller() == owner assert contract.finance() == finance assert contract.rewardToken() == ldo @@ -24,9 +22,7 @@ def test_deploy(owner, reward_programs_registry, finance, ldo, TopUpRewardProgra def test_create_evm_script_called_by_stranger(stranger, top_up_reward_programs): "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" with reverts("CALLER_IS_FORBIDDEN"): - top_up_reward_programs.createEVMScript( - stranger, encode_call_data([], []), {"from": stranger} - ) + top_up_reward_programs.createEVMScript(stranger, encode_call_data([], []), {"from": stranger}) def test_create_evm_script_data_length_mismatch(owner, top_up_reward_programs): @@ -34,7 +30,7 @@ def test_create_evm_script_data_length_mismatch(owner, top_up_reward_programs): with reverts("LENGTH_MISMATCH"): top_up_reward_programs.createEVMScript( owner, - encode_call_data(REWARD_PROGRAM_ADDRESSES, [1 ** 18]), + encode_call_data(REWARD_PROGRAM_ADDRESSES, [1**18]), ) @@ -48,17 +44,11 @@ def test_create_evm_script_zero_amount( owner, top_up_reward_programs, reward_programs_registry, evm_script_executor_stub ): "Must revert with message 'ZERO_AMOUNT' if some value in amounts has zero value" - amounts = [1 ** 18, 0] - reward_programs_registry.addRewardProgram( - REWARD_PROGRAM_ADDRESSES[0], "", {"from": evm_script_executor_stub} - ) - reward_programs_registry.addRewardProgram( - REWARD_PROGRAM_ADDRESSES[1], "", {"from": evm_script_executor_stub} - ) + amounts = [1**18, 0] + reward_programs_registry.addRewardProgram(REWARD_PROGRAM_ADDRESSES[0], "", {"from": evm_script_executor_stub}) + reward_programs_registry.addRewardProgram(REWARD_PROGRAM_ADDRESSES[1], "", {"from": evm_script_executor_stub}) with reverts("ZERO_AMOUNT"): - top_up_reward_programs.createEVMScript( - owner, encode_call_data(REWARD_PROGRAM_ADDRESSES, amounts) - ) + top_up_reward_programs.createEVMScript(owner, encode_call_data(REWARD_PROGRAM_ADDRESSES, amounts)) def test_create_evm_script_reward_program_not_allowed( @@ -79,12 +69,8 @@ def test_create_evm_script_reward_program_not_allowed( owner, encode_call_data(REWARD_PROGRAM_ADDRESSES, REWARD_PROGRAM_AMOUNTS) ) - reward_programs_registry.addRewardProgram( - REWARD_PROGRAM_ADDRESSES[0], "", {"from": evm_script_executor_stub} - ) - reward_programs_registry.addRewardProgram( - REWARD_PROGRAM_ADDRESSES[1], "", {"from": evm_script_executor_stub} - ) + reward_programs_registry.addRewardProgram(REWARD_PROGRAM_ADDRESSES[0], "", {"from": evm_script_executor_stub}) + reward_programs_registry.addRewardProgram(REWARD_PROGRAM_ADDRESSES[1], "", {"from": evm_script_executor_stub}) # case with added reward programs with reverts("REWARD_PROGRAM_NOT_ALLOWED"): @@ -96,7 +82,7 @@ def test_create_evm_script_reward_program_not_allowed( REWARD_PROGRAM_ADDRESSES[1], not_allowed_reward_program, ], - [REWARD_PROGRAM_AMOUNTS[0], REWARD_PROGRAM_AMOUNTS[1], 3 * 10 ** 18], + [REWARD_PROGRAM_AMOUNTS[0], REWARD_PROGRAM_AMOUNTS[1], 3 * 10**18], ), ) @@ -111,12 +97,8 @@ def test_create_evm_script( ): "Must create correct EVMScript if all requirements are met" # add reward programs - reward_programs_registry.addRewardProgram( - REWARD_PROGRAM_ADDRESSES[0], "", {"from": evm_script_executor_stub} - ) - reward_programs_registry.addRewardProgram( - REWARD_PROGRAM_ADDRESSES[1], "", {"from": evm_script_executor_stub} - ) + reward_programs_registry.addRewardProgram(REWARD_PROGRAM_ADDRESSES[0], "", {"from": evm_script_executor_stub}) + reward_programs_registry.addRewardProgram(REWARD_PROGRAM_ADDRESSES[1], "", {"from": evm_script_executor_stub}) evm_script = top_up_reward_programs.createEVMScript( owner, encode_call_data(REWARD_PROGRAM_ADDRESSES, REWARD_PROGRAM_AMOUNTS) @@ -156,4 +138,4 @@ def test_decode_evm_script_call_data(top_up_reward_programs): def encode_call_data(addresses, amounts): - return "0x" + encode_single("(address[],uint256[])", [addresses, amounts]).hex() + return "0x" + encode(["address[]", "uint256[]"], [addresses, amounts]).hex() diff --git a/tests/evm_script_factories/test_update_target_validators_limits.py b/tests/evm_script_factories/test_update_target_validators_limits.py new file mode 100644 index 00000000..8fe1bbb6 --- /dev/null +++ b/tests/evm_script_factories/test_update_target_validators_limits.py @@ -0,0 +1,94 @@ +import pytest +from eth_abi import encode +from brownie import reverts, UpdateTargetValidatorLimits + +from utils.evm_script import encode_call_script + + +def create_calldata(data): + return ( + "0x" + + encode( + ["(uint256,bool,uint256)[]"], + [data], + ).hex() + ) + + +@pytest.fixture(scope="module") +def update_target_validator_limits_factory(owner, node_operators_registry): + + return UpdateTargetValidatorLimits.deploy(owner, node_operators_registry, {"from": owner}) + + +def test_deploy(node_operators_registry, owner, update_target_validator_limits_factory): + "Must deploy contract with correct data" + assert update_target_validator_limits_factory.trustedCaller() == owner + assert update_target_validator_limits_factory.nodeOperatorsRegistry() == node_operators_registry + + +def test_create_evm_script_called_by_stranger(stranger, update_target_validator_limits_factory): + "Must revert with message 'CALLER_IS_FORBIDDEN' if creator isn't trustedCaller" + EVM_SCRIPT_CALLDATA = "0x" + with reverts("CALLER_IS_FORBIDDEN"): + update_target_validator_limits_factory.createEVMScript(stranger, EVM_SCRIPT_CALLDATA) + + +def test_empty_calldata(owner, update_target_validator_limits_factory): + with reverts("EMPTY_CALLDATA"): + EMPTY_CALLDATA = create_calldata([]) + update_target_validator_limits_factory.createEVMScript(owner, EMPTY_CALLDATA) + + +def test_non_sorted_calldata(owner, update_target_validator_limits_factory): + "Must revert with message 'NODE_OPERATORS_IS_NOT_SORTED' when operator ids isn't sorted" + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(1, True, 1), (0, False, 2)]) + update_target_validator_limits_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + with reverts("NODE_OPERATORS_IS_NOT_SORTED"): + NON_SORTED_CALLDATA = create_calldata([(0, True, 1), (0, True, 2)]) + update_target_validator_limits_factory.createEVMScript(owner, NON_SORTED_CALLDATA) + + +def test_operator_id_out_of_range(owner, update_target_validator_limits_factory, node_operators_registry): + "Must revert with message 'NODE_OPERATOR_INDEX_OUT_OF_RANGE' when operator id gt operators count" + + with reverts("NODE_OPERATOR_INDEX_OUT_OF_RANGE"): + node_operators_count = node_operators_registry.getNodeOperatorsCount() + CALLDATA = create_calldata([(node_operators_count, True, 1)]) + update_target_validator_limits_factory.createEVMScript(owner, CALLDATA) + + +def test_create_evm_script( + owner, + update_target_validator_limits_factory, + node_operators_registry, +): + "Must create correct EVMScript if all requirements are met" + + input_params = [(0, True, 1), (1, True, 1)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + evm_script = update_target_validator_limits_factory.createEVMScript(owner, EVM_SCRIPT_CALLDATA) + expected_evm_script = encode_call_script( + [ + ( + node_operators_registry.address, + node_operators_registry.updateTargetValidatorsLimits.encode_input( + input_param[0], input_param[1], input_param[2] + ), + ) + for input_param in input_params + ] + ) + assert evm_script == expected_evm_script + + +def test_decode_evm_script_call_data(node_operators_registry, update_target_validator_limits_factory): + "Must decode EVMScript call data correctly" + input_params = [(0, True, 1), (1, True, 1)] + + EVM_SCRIPT_CALLDATA = create_calldata(input_params) + assert update_target_validator_limits_factory.decodeEVMScriptCallData(EVM_SCRIPT_CALLDATA) == input_params diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 00000000..804a8404 --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,622 @@ +import pytest +import brownie + +import constants +import math +from utils import lido, deployment, deployed_date_time, evm_script, log +from dataclasses import dataclass + +##### +# CONSTANTS +##### + +MAX_SECONDS_IN_MONTH = 31 * 24 * 60 * 60 +STETH_ERROR_MARGIN_WEI = 2 + +##### +# ACCOUNTS +##### + + +@pytest.fixture(scope="module") +def deployer(accounts): + """Default deployer of the contracts""" + return accounts[0] + + +@pytest.fixture(scope="module") +def trusted_caller(accounts): + """EOA used as default trusted caller in the EVM script factories""" + return accounts[1] + + +@pytest.fixture(scope="module") +def stranger(accounts): + return accounts[2] + + +@pytest.fixture(scope="module") +def recipients(accounts): + @dataclass + class Recipient: + address: str + title: str + + return [ + Recipient(address=accounts[7].address, title="recipient#1"), + Recipient(address=accounts[8].address, title="recipient#2"), + Recipient(address=accounts[9].address, title="recipient#3"), + ] + + +##### +# CONTRACTS +##### + + +@pytest.fixture(scope="module") +def deployed_contracts(): + """ + To run tests on deployed contracts, set their address below + """ + return { + "EasyTrack": "", + "AllowedRecipientsFactory": "", + "AllowedRecipientsBuilder": "", + "AllowedRecipientsRegistry": "", + "AddAllowedRecipient": "", + "RemoveAllowedRecipient": "", + "TopUpAllowedRecipients": "", + } + + +@pytest.fixture(scope="module") +def load_deployed_contract(deployed_contracts): + def _load_deployed_contract(contract_name): + Contract = getattr(brownie, contract_name) + + if Contract is None: + raise Exception(f"Contract '{contract_name}' not found") + + if contract_name in deployed_contracts and deployed_contracts[contract_name] != "": + loaded_contract = Contract.at(deployed_contracts[contract_name]) + log.ok(f"Loaded contract: {contract_name}('{loaded_contract.address}')") + return loaded_contract + + return _load_deployed_contract + + +@pytest.fixture(scope="module") +def lido_contracts(): + return lido.contracts(network=brownie.network.show_active()) + + +@pytest.fixture(scope="module") +def easy_track( + EasyTrack, + EVMScriptExecutor, + lido_contracts, + deployer, + load_deployed_contract, +): + + loaded_easy_track = load_deployed_contract("EasyTrack") + + if loaded_easy_track: + lido_contracts.aragon.acl.grantPermission( + loaded_easy_track.evmScriptExecutor(), + lido_contracts.permissions.finance.CREATE_PAYMENTS_ROLE.app, + lido_contracts.permissions.finance.CREATE_PAYMENTS_ROLE.role, + {"from": lido_contracts.aragon.voting}, + ) + + if not loaded_easy_track is None: + return loaded_easy_track + + deployed_easy_track = EasyTrack.deploy( + lido_contracts.ldo, + lido_contracts.aragon.voting, + constants.MIN_MOTION_DURATION, + constants.MAX_MOTIONS_LIMIT, + constants.DEFAULT_OBJECTIONS_THRESHOLD, + {"from": deployer}, + ) + + evm_script_executor = EVMScriptExecutor.deploy( + lido_contracts.aragon.calls_script, deployed_easy_track, {"from": deployer} + ) + + deployed_easy_track.setEVMScriptExecutor(evm_script_executor, {"from": lido_contracts.aragon.voting}) + evm_script_executor.transferOwnership(lido_contracts.aragon.voting, {"from": deployer}) + + assert evm_script_executor.owner() == lido_contracts.aragon.voting + + create_payments_permission = lido_contracts.permissions.finance.CREATE_PAYMENTS_ROLE + + if not lido_contracts.aragon.acl.hasPermission( + evm_script_executor, + create_payments_permission.app, + create_payments_permission.role, + ): + lido_contracts.aragon.acl.grantPermission( + evm_script_executor, + create_payments_permission.app, + create_payments_permission.role, + {"from": lido_contracts.aragon.voting}, + ) + + return deployed_easy_track + + +@pytest.fixture(scope="module") +def enact_motion_by_creation_tx(easy_track, stranger): + def _enact_motion_by_creation_tx(creation_tx): + motion_id = creation_tx.events["MotionCreated"]["_motionId"] + motion_calldata = creation_tx.events["MotionCreated"]["_evmScriptCallData"] + + return easy_track.enactMotion(motion_id, motion_calldata, {"from": stranger}) + + return _enact_motion_by_creation_tx + + +#### +# EVM SCRIPT FACTORIES +#### + + +@pytest.fixture(scope="module") +def add_allowed_recipient_evm_script_factory( + AddAllowedRecipient, + easy_track, + lido_contracts, + trusted_caller, + load_deployed_contract, + allowed_recipients_builder, + allowed_recipients_registry, + deployer, +): + + evm_script_factory = load_deployed_contract("AddAllowedRecipient") + + if evm_script_factory is None: + tx = allowed_recipients_builder.deployAddAllowedRecipient( + trusted_caller, allowed_recipients_registry, {"from": deployer} + ) + evm_script_factory = AddAllowedRecipient.at(tx.events["AddAllowedRecipientDeployed"]["addAllowedRecipient"]) + + if not easy_track.isEVMScriptFactory(evm_script_factory): + easy_track.addEVMScriptFactory( + evm_script_factory, + deployment.create_permission(allowed_recipients_registry, "addRecipient"), + {"from": lido_contracts.aragon.voting}, + ) + log.ok(f"EVM Script Factory AddAllowedRecipient({evm_script_factory}) was added to EasyTrack") + + return evm_script_factory + + +@pytest.fixture(scope="module") +def remove_allowed_recipient_evm_script_factory( + RemoveAllowedRecipient, + easy_track, + lido_contracts, + load_deployed_contract, + allowed_recipients_builder, + allowed_recipients_registry, + deployer, + trusted_caller, +): + evm_script_factory = load_deployed_contract("RemoveAllowedRecipient") + + if evm_script_factory is None: + tx = allowed_recipients_builder.deployRemoveAllowedRecipient( + trusted_caller, allowed_recipients_registry, {"from": deployer} + ) + + evm_script_factory = RemoveAllowedRecipient.at( + tx.events["RemoveAllowedRecipientDeployed"]["removeAllowedRecipient"] + ) + + if not easy_track.isEVMScriptFactory(evm_script_factory): + easy_track.addEVMScriptFactory( + evm_script_factory, + deployment.create_permission(allowed_recipients_registry, "removeRecipient"), + {"from": lido_contracts.aragon.voting}, + ) + log.ok(f"EVM Script Factory RemoveAllowedRecipient({evm_script_factory}) was added to EasyTrack") + + return evm_script_factory + + +@pytest.fixture(scope="module") +def add_allowed_recipient_by_motion(AllowedRecipientsRegistry, easy_track, stranger): + def _add_allowed_recipient_via_motion(add_allowed_recipient_evm_script_factory, recipient_address, recipient_title): + allowed_recipients_registry = AllowedRecipientsRegistry.at( + add_allowed_recipient_evm_script_factory.allowedRecipientsRegistry() + ) + + tx = easy_track.createMotion( + add_allowed_recipient_evm_script_factory, + evm_script.encode_calldata(["address", "string"], [recipient_address, recipient_title]), + {"from": add_allowed_recipient_evm_script_factory.trustedCaller()}, + ) + + brownie.chain.sleep(easy_track.motionDuration() + 100) + + tx = easy_track.enactMotion( + tx.events["MotionCreated"]["_motionId"], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + + assert allowed_recipients_registry.isRecipientAllowed(recipient_address) + return tx + + return _add_allowed_recipient_via_motion + + +@pytest.fixture(scope="module") +def remove_allowed_recipient_by_motion(AllowedRecipientsRegistry, easy_track, stranger): + def _remove_recipient_by_motion(remove_allowed_recipient_evm_script_factory, recipient_address): + + allowed_recipients_registry = AllowedRecipientsRegistry.at( + remove_allowed_recipient_evm_script_factory.allowedRecipientsRegistry() + ) + call_data = evm_script.encode_calldata(["address"], [recipient_address]) + + tx = easy_track.createMotion( + remove_allowed_recipient_evm_script_factory, + call_data, + {"from": remove_allowed_recipient_evm_script_factory.trustedCaller()}, + ) + + brownie.chain.sleep(easy_track.motionDuration() + 100) + + tx = easy_track.enactMotion( + tx.events["MotionCreated"]["_motionId"], + call_data, + {"from": stranger}, + ) + assert not allowed_recipients_registry.isRecipientAllowed(recipient_address) + return tx + + return _remove_recipient_by_motion + + +@pytest.fixture(scope="module") +def top_up_allowed_recipients_evm_script_factory( + TopUpAllowedRecipients, + easy_track, + lido_contracts, + load_deployed_contract, + allowed_recipients_builder, + allowed_recipients_registry, + trusted_caller, + deployer, +): + + evm_script_factory = load_deployed_contract("TopUpAllowedRecipients") + + if evm_script_factory is None: + tx = allowed_recipients_builder.deployTopUpAllowedRecipients( + trusted_caller, + allowed_recipients_registry, + lido_contracts.ldo, + {"from": deployer}, + ) + + evm_script_factory = TopUpAllowedRecipients.at( + tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + ) + + if not easy_track.isEVMScriptFactory(evm_script_factory): + easy_track.addEVMScriptFactory( + evm_script_factory, + deployment.create_permission(lido_contracts.aragon.finance, "newImmediatePayment") + + deployment.create_permission(allowed_recipients_registry, "updateSpentAmount")[2:], + {"from": lido_contracts.aragon.voting}, + ) + log.ok(f"EVM Script Factory TopUpAllowedRecipients({evm_script_factory}) was added to EasyTrack") + + return evm_script_factory + + +#### +# ALLOWED RECIPIENTS FIXTURES +#### + + +@pytest.fixture(scope="module") +def create_add_allowed_recipient_motion(easy_track): + def _create_add_allowed_recipient_motion( + add_allowed_recipient_evm_script_factory, recipient_address, recipient_title + ): + return easy_track.createMotion( + add_allowed_recipient_evm_script_factory, + evm_script.encode_calldata(["address", "string"], [recipient_address, recipient_title]), + {"from": add_allowed_recipient_evm_script_factory.trustedCaller()}, + ) + + return _create_add_allowed_recipient_motion + + +@pytest.fixture(scope="module") +def create_top_up_allowed_recipients_motion(easy_track): + def _create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + recipient_addresses, + top_up_amounts, + ): + return easy_track.createMotion( + top_up_allowed_recipients_evm_script_factory, + evm_script.encode_calldata(["address[]", "uint256[]"], [recipient_addresses, top_up_amounts]), + {"from": top_up_allowed_recipients_evm_script_factory.trustedCaller()}, + ) + + return _create_top_up_allowed_recipients_motion + + +@pytest.fixture(scope="module") +def top_up_allowed_recipient_by_motion( + easy_track, + create_top_up_allowed_recipients_motion, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + def _top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, recipient_addresses, top_up_amounts, spent_amount=0 + ): + motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + recipient_addresses, + top_up_amounts, + ) + + enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx, spent_amount) + + return _top_up_allowed_recipient_by_motion + + +@pytest.fixture(scope="module") +def get_balances(interface, accounts): + def _get_balances(token, recipients): + if token == brownie.ZERO_ADDRESS: + return [accounts.at(r).balance() for r in recipients] + return [interface.ERC20(token).balanceOf(r) for r in recipients] + + return _get_balances + + +@pytest.fixture(scope="module") +def enact_top_up_allowed_recipient_motion_by_creation_tx( + TopUpAllowedRecipients, + interface, + easy_track, + get_balances, + lido_contracts, + enact_motion_by_creation_tx, + check_top_up_motion_enactment, +): + def _enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx, spent_amount=0): + top_up_allowed_recipients_evm_script_factory = TopUpAllowedRecipients.at( + motion_creation_tx.events["MotionCreated"]["_evmScriptFactory"] + ) + + ( + recipients, + amounts, + ) = top_up_allowed_recipients_evm_script_factory.decodeEVMScriptCallData( + motion_creation_tx.events["MotionCreated"]["_evmScriptCallData"] + ) + + top_up_token = top_up_allowed_recipients_evm_script_factory.token() + + (sender_balance_before,) = get_balances(top_up_token, [lido_contracts.aragon.agent]) + recipients_balances_before = get_balances(top_up_token, recipients) + sender_shares_balance_before = 0 + recipients_shares_balance_before = 0 + if top_up_token == lido_contracts.steth: + sender_shares_balance_before = lido_contracts.steth.sharesOf(lido_contracts.aragon.agent) + for r in recipients: + recipients_shares_balance_before += lido_contracts.steth.sharesOf(r) + + motion_data = easy_track.getMotion(motion_creation_tx.events["MotionCreated"]["_motionId"]).dict() + + # If motion not finished wait end of it + if motion_data["startDate"] + motion_data["duration"] > brownie.chain[-1]["timestamp"]: + brownie.chain.sleep(easy_track.motionDuration() + 100) + + motion_enactment_tx = enact_motion_by_creation_tx(motion_creation_tx) + + check_top_up_motion_enactment( + top_up_allowed_recipients_evm_script_factory=top_up_allowed_recipients_evm_script_factory, + top_up_motion_enactment_tx=motion_enactment_tx, + sender_balance_before=sender_balance_before, + recipients_balances_before=recipients_balances_before, + sender_shares_balance_before=sender_shares_balance_before, + recipients_shares_balance_before=recipients_shares_balance_before, + top_up_recipients=recipients, + top_up_amounts=amounts, + spent_amount=spent_amount, + ) + + return _enact_top_up_allowed_recipient_motion_by_creation_tx + + +@pytest.fixture(scope="module") +def check_top_up_motion_enactment(AllowedRecipientsRegistry, get_balances, lido_contracts): + """Note: this check works correctly only when was payment in the period""" + + def _check_top_up_motion_enactment( + top_up_allowed_recipients_evm_script_factory, + top_up_motion_enactment_tx, + sender_balance_before, + recipients_balances_before, + sender_shares_balance_before, + recipients_shares_balance_before, + top_up_recipients, + top_up_amounts, + spent_amount, + ): + allowed_recipients_registry = AllowedRecipientsRegistry.at( + top_up_allowed_recipients_evm_script_factory.allowedRecipientsRegistry() + ) + limit, duration = allowed_recipients_registry.getLimitParameters() + + spending = sum(top_up_amounts) + spendable = limit - (spending + spent_amount) + + assert allowed_recipients_registry.isUnderSpendableBalance(spendable, 0) + assert allowed_recipients_registry.isUnderSpendableBalance(limit, duration * MAX_SECONDS_IN_MONTH) + assert allowed_recipients_registry.getPeriodState()["_alreadySpentAmount"] == spending + spent_amount + assert allowed_recipients_registry.getPeriodState()["_spendableBalanceInPeriod"] == spendable + + top_up_token = top_up_allowed_recipients_evm_script_factory.token() + (sender_balance,) = get_balances(top_up_token, [lido_contracts.aragon.agent]) + recipients_balances = get_balances( + top_up_token, + top_up_recipients, + ) + + if top_up_token == lido_contracts.steth: + assert math.isclose(sender_balance, sender_balance_before - spending, abs_tol=STETH_ERROR_MARGIN_WEI) + + sender_shares_balance_after = lido_contracts.steth.sharesOf(lido_contracts.aragon.agent) + recipients_shares_balance_after = 0 + for r in top_up_recipients: + recipients_shares_balance_after += lido_contracts.steth.sharesOf(r) + assert sender_shares_balance_before >= sender_shares_balance_after + assert ( + sender_shares_balance_before - sender_shares_balance_after + == recipients_shares_balance_after - recipients_shares_balance_before + ) + else: + assert sender_balance == sender_balance_before - spending + + for before, now, payment in zip(recipients_balances_before, recipients_balances, top_up_amounts): + if top_up_token == lido_contracts.steth: + assert math.isclose(now, before + payment, abs_tol=STETH_ERROR_MARGIN_WEI) + else: + assert now == before + payment + + assert "SpendableAmountChanged" in top_up_motion_enactment_tx.events + assert ( + top_up_motion_enactment_tx.events["SpendableAmountChanged"]["_alreadySpentAmount"] + == spending + spent_amount + ) + assert top_up_motion_enactment_tx.events["SpendableAmountChanged"]["_spendableBalance"] == spendable + + return _check_top_up_motion_enactment + + +@pytest.fixture(scope="module") +def allowed_recipients_factory(AllowedRecipientsFactory, load_deployed_contract, deployer): + + loaded_allowed_recipients_factory = load_deployed_contract("AllowedRecipientsFactory") + + if not loaded_allowed_recipients_factory is None: + return loaded_allowed_recipients_factory + + return AllowedRecipientsFactory.deploy({"from": deployer}) + + +@pytest.fixture(scope="module") +def allowed_recipients_builder( + AllowedRecipientsBuilder, + lido_contracts, + load_deployed_contract, + allowed_recipients_factory, + bokky_poo_bahs_date_time_contract, + easy_track, + deployer, +): + + loaded_allowed_recipients_builder = load_deployed_contract("AllowedRecipientsBuilder") + + if not loaded_allowed_recipients_builder is None: + return loaded_allowed_recipients_builder + + return AllowedRecipientsBuilder.deploy( + allowed_recipients_factory, + lido_contracts.aragon.agent, + easy_track, + lido_contracts.aragon.finance, + bokky_poo_bahs_date_time_contract, + {"from": deployer}, + ) + + +@pytest.fixture(scope="module") +def allowed_recipients_default_params(): + @dataclass + class AllowedRecipientsDefaultParams: + limit: int + period_duration_months: int + spent_amount: int + + return AllowedRecipientsDefaultParams(limit=100 * 10**18, period_duration_months=1, spent_amount=0) + + +@pytest.fixture(scope="module") +def allowed_recipients_registry( + AllowedRecipientsRegistry, + allowed_recipients_default_params, + allowed_recipients_builder, + load_deployed_contract, + lido_contracts, + easy_track, + deployer, +): + allowed_recipients_registry = load_deployed_contract("AllowedRecipientsRegistry") + + if allowed_recipients_registry is None: + tx = allowed_recipients_builder.deployAllowedRecipientsRegistry( + allowed_recipients_default_params.limit, + allowed_recipients_default_params.period_duration_months, + [], + [], + allowed_recipients_default_params.spent_amount, + True, + {"from": deployer}, + ) + + allowed_recipients_registry = AllowedRecipientsRegistry.at( + tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + ) + + if not allowed_recipients_registry.hasRole( + allowed_recipients_registry.ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE(), + easy_track.evmScriptExecutor(), + ): + allowed_recipients_registry.grantRole( + allowed_recipients_registry.ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE(), + easy_track.evmScriptExecutor(), + {"from": lido_contracts.aragon.agent}, + ) + + if not allowed_recipients_registry.hasRole( + allowed_recipients_registry.REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE(), + easy_track.evmScriptExecutor(), + ): + allowed_recipients_registry.grantRole( + allowed_recipients_registry.REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE(), + easy_track.evmScriptExecutor(), + {"from": lido_contracts.aragon.agent}, + ) + + return allowed_recipients_registry + + +@pytest.fixture(scope="module") +def allowed_recipients_limit_params(allowed_recipients_registry): + @dataclass + class AllowedRecipientsLimits: + limit: int + duration: int + + limit, duration = allowed_recipients_registry.getLimitParameters() + return AllowedRecipientsLimits(limit, duration) + + +@pytest.fixture(scope="module") +def bokky_poo_bahs_date_time_contract(): + return deployed_date_time.date_time_contract(network=brownie.network.show_active()) diff --git a/tests/integration/test_allowed_recipients_happy_path.py b/tests/integration/test_allowed_recipients_happy_path.py new file mode 100644 index 00000000..0fd25270 --- /dev/null +++ b/tests/integration/test_allowed_recipients_happy_path.py @@ -0,0 +1,301 @@ +import pytest +from dataclasses import dataclass +from brownie import ( + chain, + reverts, + AllowedRecipientsRegistry, + TopUpAllowedRecipients, + AddAllowedRecipient, + RemoveAllowedRecipient, +) +from utils import deployment, test_helpers + +MAX_SECONDS_IN_MONTH = 31 * 24 * 60 * 60 + + +@dataclass +class SingleRecipientTopUpOnlySetup: + allowed_recipients_registry: AllowedRecipientsRegistry + top_up_allowed_recipients_evm_script_factory: TopUpAllowedRecipients + + +@dataclass +class FullSetup(SingleRecipientTopUpOnlySetup): + add_allowed_recipient_evm_script_factory: AddAllowedRecipient + remove_allowed_recipient_evm_script_factory: RemoveAllowedRecipient + + +@pytest.fixture(scope="module") +def allowed_recipient(recipients): + return recipients[0] + + +@pytest.fixture(scope="module") +def new_recipient(recipients): + return recipients[1] + + +@pytest.fixture(scope="module") +def single_recipient_top_up_only_setup( + AllowedRecipientsRegistry, + TopUpAllowedRecipients, + easy_track, + lido_contracts, + allowed_recipient, + allowed_recipients_builder, + allowed_recipients_default_params, + deployer, +): + + deploy_tx = allowed_recipients_builder.deploySingleRecipientTopUpOnlySetup( + allowed_recipient.address, + allowed_recipient.title, + lido_contracts.ldo, + allowed_recipients_default_params.limit, + allowed_recipients_default_params.period_duration_months, + allowed_recipients_default_params.spent_amount, + {"from": deployer}, + ) + + allowed_recipients_registry = AllowedRecipientsRegistry.at( + deploy_tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + ) + top_up_allowed_recipients_evm_script_factory = TopUpAllowedRecipients.at( + deploy_tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + ) + easy_track.addEVMScriptFactory( + top_up_allowed_recipients_evm_script_factory, + deployment.create_permission(lido_contracts.aragon.finance, "newImmediatePayment") + + deployment.create_permission(allowed_recipients_registry, "updateSpentAmount")[2:], + {"from": lido_contracts.aragon.voting}, + ) + return SingleRecipientTopUpOnlySetup(allowed_recipients_registry, top_up_allowed_recipients_evm_script_factory) + + +@pytest.fixture(scope="module") +def full_setup( + AllowedRecipientsRegistry, + AddAllowedRecipient, + TopUpAllowedRecipients, + RemoveAllowedRecipient, + easy_track, + allowed_recipients_builder, + trusted_caller, + lido_contracts, + allowed_recipients_default_params, + deployer, +): + deploy_tx = allowed_recipients_builder.deployFullSetup( + trusted_caller, + lido_contracts.ldo, + allowed_recipients_default_params.limit, + allowed_recipients_default_params.period_duration_months, + [], + [], + allowed_recipients_default_params.spent_amount, + {"from": deployer}, + ) + + allowed_recipients_registry = AllowedRecipientsRegistry.at( + deploy_tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + ) + + add_allowed_recipient_evm_script_factory = AddAllowedRecipient.at( + deploy_tx.events["AddAllowedRecipientDeployed"]["addAllowedRecipient"] + ) + + easy_track.addEVMScriptFactory( + add_allowed_recipient_evm_script_factory, + deployment.create_permission(allowed_recipients_registry, "addRecipient"), + {"from": lido_contracts.aragon.voting}, + ) + + remove_allowed_recipient_evm_script_factory = RemoveAllowedRecipient.at( + deploy_tx.events["RemoveAllowedRecipientDeployed"]["removeAllowedRecipient"] + ) + easy_track.addEVMScriptFactory( + remove_allowed_recipient_evm_script_factory, + deployment.create_permission(allowed_recipients_registry, "removeRecipient"), + {"from": lido_contracts.aragon.voting}, + ) + + top_up_allowed_recipients_evm_script_factory = TopUpAllowedRecipients.at( + deploy_tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + ) + easy_track.addEVMScriptFactory( + top_up_allowed_recipients_evm_script_factory, + deployment.create_permission(lido_contracts.aragon.finance, "newImmediatePayment") + + deployment.create_permission(allowed_recipients_registry, "updateSpentAmount")[2:], + {"from": lido_contracts.aragon.voting}, + ) + + return FullSetup( + allowed_recipients_registry, + top_up_allowed_recipients_evm_script_factory, + add_allowed_recipient_evm_script_factory, + remove_allowed_recipient_evm_script_factory, + ) + + +def test_single_recipient_top_up_only_setup_happy_path( + lido_contracts, + evm_script_executor, + allowed_recipients_default_params, + single_recipient_top_up_only_setup, + top_up_allowed_recipient_by_motion, + allowed_recipient, + new_recipient, +): + first_top_up_amount = 50 * 10**18 + second_top_up_amount = 100 * 10**18 + + test_helpers.advance_chain_time_to_beginning_of_the_next_period( + allowed_recipients_default_params.period_duration_months + ) + + allowed_recipients_registry = single_recipient_top_up_only_setup.allowed_recipients_registry + top_up_allowed_recipients_evm_script_factory = ( + single_recipient_top_up_only_setup.top_up_allowed_recipients_evm_script_factory + ) + + # Top up allowed recipient + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [allowed_recipient.address], + [first_top_up_amount], + ) + + # Validate Aragon Agent can remove recipient + assert allowed_recipients_registry.isRecipientAllowed(allowed_recipient.address) + + allowed_recipients_registry.removeRecipient(allowed_recipient.address, {"from": lido_contracts.aragon.agent}) + + assert not allowed_recipients_registry.isRecipientAllowed(allowed_recipient.address) + + # Validate EVM Script Executor can't add recipient + with reverts( + test_helpers.access_revert_message( + evm_script_executor, + allowed_recipients_registry.ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE(), + ) + ): + allowed_recipients_registry.addRecipient( + new_recipient.address, new_recipient.title, {"from": evm_script_executor} + ) + + # Validate Aragon Agent can add recipient + allowed_recipients_registry.addRecipient( + new_recipient.address, + new_recipient.title, + {"from": lido_contracts.aragon.agent}, + ) + + assert allowed_recipients_registry.isRecipientAllowed(new_recipient.address) + + # Validate EVM Script Executor can't remove recipient + with reverts( + test_helpers.access_revert_message( + evm_script_executor, + allowed_recipients_registry.REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE(), + ) + ): + allowed_recipients_registry.removeRecipient(new_recipient.address, {"from": evm_script_executor}) + + # wait next period + + chain.sleep(allowed_recipients_default_params.period_duration_months * MAX_SECONDS_IN_MONTH) + + # Top up newly added recipient + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [new_recipient.address], + [second_top_up_amount], + ) + + # Validate motion creation fails if the limit was exceeded + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [new_recipient.address], + [1], + ) + + +def test_full_setup_happy_path( + full_setup, + lido_contracts, + add_allowed_recipient_by_motion, + top_up_allowed_recipient_by_motion, + remove_allowed_recipient_by_motion, + allowed_recipients_default_params, + allowed_recipient, + new_recipient, +): + first_top_up_amount = 50 * 10**18 + second_top_up_amount = 100 * 10**18 + + test_helpers.advance_chain_time_to_beginning_of_the_next_period( + allowed_recipients_default_params.period_duration_months + ) + + # Add allowed recipient by motion + add_allowed_recipient_evm_script_factory = full_setup.add_allowed_recipient_evm_script_factory + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + # Top up allowed recipient by motion + top_up_allowed_recipients_evm_script_factory = full_setup.top_up_allowed_recipients_evm_script_factory + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [allowed_recipient.address], + [first_top_up_amount], + ) + + # Remove allowed recipient by motion + remove_allowed_recipient_evm_script_factory = full_setup.remove_allowed_recipient_evm_script_factory + remove_allowed_recipient_by_motion(remove_allowed_recipient_evm_script_factory, allowed_recipient.address) + + # Aragon's Agent can add new recipients + allowed_recipients_registry = full_setup.allowed_recipients_registry + + assert not allowed_recipients_registry.isRecipientAllowed(new_recipient.address) + allowed_recipients_registry.addRecipient( + new_recipient.address, + new_recipient.title, + {"from": lido_contracts.aragon.agent}, + ) + assert allowed_recipients_registry.isRecipientAllowed(new_recipient.address) + + # Wait for next period + chain.sleep(allowed_recipients_default_params.period_duration_months * MAX_SECONDS_IN_MONTH) + + # Top up newly allowed recipient by motion + top_up_allowed_recipients_evm_script_factory = full_setup.top_up_allowed_recipients_evm_script_factory + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [new_recipient.address], + [second_top_up_amount], + ) + + # Validate motion creation cause limit was spent + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [new_recipient.address], + [1], + ) + + # Aragon's Agent can remove recipients + allowed_recipients_registry = full_setup.allowed_recipients_registry + + assert allowed_recipients_registry.isRecipientAllowed(new_recipient.address) + allowed_recipients_registry.removeRecipient( + new_recipient.address, + {"from": lido_contracts.aragon.agent}, + ) + assert not allowed_recipients_registry.isRecipientAllowed(new_recipient.address) diff --git a/tests/integration/test_allowed_recipients_motions.py b/tests/integration/test_allowed_recipients_motions.py new file mode 100644 index 00000000..cffcaf71 --- /dev/null +++ b/tests/integration/test_allowed_recipients_motions.py @@ -0,0 +1,936 @@ +import pytest + +from brownie import reverts +from brownie.network import chain + +from utils import evm_script, test_helpers + +MAX_SECONDS_IN_MONTH = 31 * 24 * 60 * 60 + + +def test_add_recipient_motion( + recipients, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, +): + recipient = recipients[0] + + allowed_recipients_count_before = len(allowed_recipients_registry.getAllowedRecipients()) + + motion_enactment_tx = add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, recipient.address, recipient.title + ) + test_helpers.assert_event_exists( + motion_enactment_tx, + "RecipientAdded", + {"_recipient": recipient.address, "_title": recipient.title}, + ) + assert len(allowed_recipients_registry.getAllowedRecipients()) == allowed_recipients_count_before + 1 + + +def test_add_multiple_recipients_by_concurrent_motions( + recipients, + easy_track, + allowed_recipients_registry, + enact_motion_by_creation_tx, + create_add_allowed_recipient_motion, + add_allowed_recipient_evm_script_factory, +): + first_recipient, second_recipient = recipients[:2] + + allowed_recipients_count_before = len(allowed_recipients_registry.getAllowedRecipients()) + + first_motion_creation_tx = create_add_allowed_recipient_motion( + add_allowed_recipient_evm_script_factory, + first_recipient.address, + first_recipient.title, + ) + + second_motion_creation_tx = create_add_allowed_recipient_motion( + add_allowed_recipient_evm_script_factory, + second_recipient.address, + second_recipient.title, + ) + + chain.sleep(easy_track.motionDuration() + 100) + + enact_motion_by_creation_tx(first_motion_creation_tx) + enact_motion_by_creation_tx(second_motion_creation_tx) + + assert allowed_recipients_registry.isRecipientAllowed(first_recipient.address) + assert allowed_recipients_registry.isRecipientAllowed(second_recipient.address) + assert len(allowed_recipients_registry.getAllowedRecipients()) == allowed_recipients_count_before + 2 + + +def test_fail_add_same_recipient_by_second_concurrent_motion( + recipients, + easy_track, + enact_motion_by_creation_tx, + create_add_allowed_recipient_motion, + add_allowed_recipient_evm_script_factory, +): + recipient = recipients[0] + + first_motion_creation_tx = create_add_allowed_recipient_motion( + add_allowed_recipient_evm_script_factory, + recipient.address, + recipient.title, + ) + + second_motion_creation_tx = create_add_allowed_recipient_motion( + add_allowed_recipient_evm_script_factory, + recipient.address, + recipient.title, + ) + + chain.sleep(easy_track.motionDuration() + 100) + + enact_motion_by_creation_tx(first_motion_creation_tx) + + with reverts("ALLOWED_RECIPIENT_ALREADY_ADDED"): + enact_motion_by_creation_tx(second_motion_creation_tx) + + +def test_fail_if_add_same_recipient_twice( + recipients, + add_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, +): + allowed_recipient = recipients[0] + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + with reverts("ALLOWED_RECIPIENT_ALREADY_ADDED"): + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + +def test_remove_recipient_motion( + recipients, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + remove_allowed_recipient_evm_script_factory, + remove_allowed_recipient_by_motion, +): + allowed_recipient = recipients[0] + + allowed_recipients_count_before = len(allowed_recipients_registry.getAllowedRecipients()) + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + motion_enactment_tx = remove_allowed_recipient_by_motion( + remove_allowed_recipient_evm_script_factory, allowed_recipient.address + ) + + test_helpers.assert_event_exists( + motion_enactment_tx, + "RecipientRemoved", + {"_recipient": allowed_recipient.address}, + ) + + assert len(allowed_recipients_registry.getAllowedRecipients()) == allowed_recipients_count_before + + +def test_fail_remove_recipient_if_empty_allowed_recipients_list( + recipients, + allowed_recipients_registry, + remove_allowed_recipient_by_motion, + remove_allowed_recipient_evm_script_factory, +): + + allowed_recipients = allowed_recipients_registry.getAllowedRecipients() + for allowed_recipient in allowed_recipients: + remove_allowed_recipient_by_motion(remove_allowed_recipient_evm_script_factory, allowed_recipient) + + assert len(allowed_recipients_registry.getAllowedRecipients()) == 0 + + with reverts("ALLOWED_RECIPIENT_NOT_FOUND"): + remove_allowed_recipient_by_motion(remove_allowed_recipient_evm_script_factory, recipients[0].address) + + +def test_fail_remove_recipient_if_it_is_not_allowed( + recipients, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + remove_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + remove_allowed_recipient_evm_script_factory, +): + allowed_recipient, not_allowed_recipient = recipients[0], recipients[1] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + assert len(allowed_recipients_registry.getAllowedRecipients()) > 0 + assert not allowed_recipients_registry.isRecipientAllowed(not_allowed_recipient.address) + + with reverts("ALLOWED_RECIPIENT_NOT_FOUND"): + remove_allowed_recipient_by_motion(remove_allowed_recipient_evm_script_factory, not_allowed_recipient.address) + + +def test_top_up_single_recipient( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + top_up_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, +): + allowed_recipient = recipients[0] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + top_up_recipient_addresses = [allowed_recipient.address] + top_up_amounts = [2 * 10**18] + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + top_up_recipient_addresses, + top_up_amounts, + ) + + +def test_top_up_single_recipient_several_times_in_period( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + top_up_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, +): + allowed_recipient = recipients[0] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + top_up_recipient_addresses = [allowed_recipient.address] + top_up_amounts = [int(allowed_recipients_limit_params.limit / 2)] + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + top_up_recipient_addresses, + top_up_amounts, + ) + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, top_up_recipient_addresses, top_up_amounts, sum(top_up_amounts) + ) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + top_up_recipient_addresses, + [1], + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + top_up_recipient_addresses, + [allowed_recipients_limit_params.limit], + ) + + +def test_top_up_multiple_recipients( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + top_up_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, +): + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + top_up_amounts = [2 * 10**18, 1 * 10**18] + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + +def test_top_up_motion_enacted_in_next_period( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + top_up_amounts = [int(3e18), int(90e18)] + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + # Wait for next period + chain.sleep(allowed_recipients_limit_params.duration * MAX_SECONDS_IN_MONTH) + + enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx) + + +def test_top_up_motion_ended_and_enacted_in_next_period( + recipients, + easy_track, + allowed_recipients_limit_params, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + top_up_amounts = [int(3e18), int(90e18)] + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + test_helpers.advance_chain_time_to_n_seconds_before_current_period_end( + allowed_recipients_limit_params.duration, easy_track.motionDuration() // 2 + ) + + motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + _, _, *old_period_range = allowed_recipients_registry.getPeriodState() + + enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx) + + _, _, *new_period_range = allowed_recipients_registry.getPeriodState() + assert ( + old_period_range != new_period_range + ), "check periods when the motion was created and when it ended are different" + + +def test_top_up_motion_enacted_in_second_next_period( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + top_up_amounts = [int(3e18), int(90e18)] + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + chain.sleep(2 * allowed_recipients_limit_params.duration * MAX_SECONDS_IN_MONTH) + + enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx) + + +def test_spendable_balance_is_renewed_in_next_period( + recipients, + allowed_recipients_limit_params, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + top_up_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, +): + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + assert allowed_recipients_registry.spendableBalance() == allowed_recipients_limit_params.limit + + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + top_up_amounts = [ + int(allowed_recipients_limit_params.limit // 10**18 * 0.1) * 10**18, + int(allowed_recipients_limit_params.limit // 10**18 * 0.9) * 10**18, + ] + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + amount_spent = sum(top_up_amounts) + assert allowed_recipients_registry.getPeriodState()[0] == amount_spent + assert allowed_recipients_registry.spendableBalance() == allowed_recipients_limit_params.limit - amount_spent + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [allowed_recipients[0].address], + [1], + ) + + chain.sleep(allowed_recipients_limit_params.duration * MAX_SECONDS_IN_MONTH) + + # cannot just check the views `spendableBalance` and `getPeriodState` + # because they are not updated without a call of updateSpentAmount + # or setLimitParameters. So trying to make a full period limit amount payout + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [allowed_recipients[0].address], + [allowed_recipients_limit_params.limit], + ) + + assert allowed_recipients_registry.getPeriodState()[0] == allowed_recipients_limit_params.limit + assert allowed_recipients_registry.spendableBalance() == 0 + + +def test_fail_enact_top_up_motion_if_recipient_removed_by_other_motion( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + remove_allowed_recipient_by_motion, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + remove_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + recipient_to_remove = allowed_recipients[0] + top_up_amounts = [int(40e18), int(30e18)] + + motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + remove_allowed_recipient_by_motion(remove_allowed_recipient_evm_script_factory, recipient_to_remove.address) + + with reverts("RECIPIENT_NOT_ALLOWED"): + enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx) + + +def test_fail_create_top_up_motion_if_exceeds_limit( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, +): + allowed_recipient = recipients[0] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipient.address, + allowed_recipient.title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + exceeded_top_up_amounts = [allowed_recipients_limit_params.limit + 1] + create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [allowed_recipient.address], + exceeded_top_up_amounts, + ) + + +def test_fail_to_create_top_up_motion_which_exceeds_spendable( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + top_up_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, +): + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + first_top_up_amounts = [ + int(allowed_recipients_limit_params.limit // 10**18 * 0.4) * 10**18, + int(allowed_recipients_limit_params.limit // 10**18 * 0.6) * 10**18, + ] + + assert sum(first_top_up_amounts) == allowed_recipients_limit_params.limit + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + first_top_up_amounts, + ) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + second_top_up_amounts = [1, 1] + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + second_top_up_amounts, + ) + + +def test_fail_2nd_top_up_motion_enactment_due_limit_but_can_enact_in_next( + recipients, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + first_top_up_amount = [ + int(allowed_recipients_limit_params.limit // 10**18 * 0.4) * 10**18, + int(allowed_recipients_limit_params.limit // 10**18 * 0.3) * 10**18, + ] + second_top_up_amount = [ + int(allowed_recipients_limit_params.limit // 10**18 * 0.3) * 10**18, + int(allowed_recipients_limit_params.limit // 10**18 * 0.2) * 10**18, + ] + + assert sum(first_top_up_amount + second_top_up_amount) > allowed_recipients_limit_params.limit + first_motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + first_top_up_amount, + ) + second_motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + second_top_up_amount, + ) + + enact_top_up_allowed_recipient_motion_by_creation_tx(first_motion_creation_tx) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + enact_top_up_allowed_recipient_motion_by_creation_tx(second_motion_creation_tx) + + chain.sleep(allowed_recipients_limit_params.duration * MAX_SECONDS_IN_MONTH) + + enact_top_up_allowed_recipient_motion_by_creation_tx(second_motion_creation_tx) + + +def test_fail_2nd_top_up_motion_creation_in_period_if_it_exceeds_spendable( + recipients, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + allowed_recipients_limit_params, + top_up_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, +): + """Revert 2nd payout which together with 1st payout exceed the current period limit""" + + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + first_top_up_amounts = [ + int(allowed_recipients_limit_params.limit // 10**18 * 0.03) * 10**18, + int(allowed_recipients_limit_params.limit // 10**18 * 0.9) * 10**18, + ] + second_top_up_amounts = [ + int(allowed_recipients_limit_params.limit // 10**18 * 0.05) * 10**18, + int(allowed_recipients_limit_params.limit // 10**18 * 0.04) * 10**18, + ] + + assert sum(first_top_up_amounts + second_top_up_amounts) > allowed_recipients_limit_params.limit + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + first_top_up_amounts, + ) + + assert sum(second_top_up_amounts) > allowed_recipients_registry.spendableBalance() + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + second_top_up_amounts, + ) + + +def test_fail_top_up_if_limit_decreased_while_motion_is_in_flight( + recipients, + lido_contracts, + allowed_recipients_registry, + allowed_recipients_limit_params, + add_allowed_recipient_by_motion, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + allowed_recipients = recipients[:1] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + top_up_amounts = [allowed_recipients_limit_params.limit] + motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + allowed_recipients_registry.setLimitParameters( + allowed_recipients_limit_params.limit // 2, + allowed_recipients_limit_params.duration, + {"from": lido_contracts.aragon.agent}, + ) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx) + + +def test_top_up_if_limit_increased_while_motion_is_in_flight( + recipients, + lido_contracts, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + allowed_recipients_limit_params, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + + allowed_recipients = recipients[:1] + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + top_up_amounts = [allowed_recipients_limit_params.limit] + motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + top_up_amounts, + ) + + allowed_recipients_registry.setLimitParameters( + 3 * allowed_recipients_limit_params.limit, + allowed_recipients_limit_params.duration, + {"from": lido_contracts.aragon.agent}, + ) + + enact_top_up_allowed_recipient_motion_by_creation_tx(motion_creation_tx) + + +def test_two_motion_seconds_failed_to_enact_due_limit_but_succeeded_after_limit_increased( + easy_track, + recipients, + lido_contracts, + enact_motion_by_creation_tx, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + allowed_recipients_limit_params, + create_top_up_allowed_recipients_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + enact_top_up_allowed_recipient_motion_by_creation_tx, +): + allowed_recipients = recipients[:2] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[1].address, + allowed_recipients[1].title, + ) + + test_helpers.advance_chain_time_to_beginning_of_the_next_period(allowed_recipients_limit_params.duration) + + first_top_up_amounts = [ + int(allowed_recipients_limit_params.limit // 10**18 * 0.4) * 10**18, + int(allowed_recipients_limit_params.limit // 10**18 * 0.6) * 10**18, + ] + assert sum(first_top_up_amounts) == allowed_recipients_limit_params.limit + second_top_up_amounts = [1, 1] + + first_motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + first_top_up_amounts, + ) + + second_motion_creation_tx = create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + second_top_up_amounts, + ) + + enact_top_up_allowed_recipient_motion_by_creation_tx(first_motion_creation_tx) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + enact_top_up_allowed_recipient_motion_by_creation_tx(second_motion_creation_tx) + + allowed_recipients_registry.setLimitParameters( + allowed_recipients_limit_params.limit + sum(second_top_up_amounts), + allowed_recipients_limit_params.duration, + {"from": lido_contracts.aragon.agent}, + ) + + chain.sleep(easy_track.motionDuration() + 100) + + # We don't run check_top_up_motion_enactment fixture because + # was another payment in the same period and check will fail + enact_motion_by_creation_tx(second_motion_creation_tx) + + +@pytest.mark.parametrize("initial_period_duration,new_period_duration", [(3, 2), (3, 6), (12, 1), (1, 12)]) +def test_top_up_spendable_renewal_if_period_duration_changed( + recipients, + allowed_recipients_registry, + add_allowed_recipient_by_motion, + lido_contracts, + create_top_up_allowed_recipients_motion, + top_up_allowed_recipient_by_motion, + add_allowed_recipient_evm_script_factory, + top_up_allowed_recipients_evm_script_factory, + initial_period_duration: int, + new_period_duration: int, +): + period_limit = 100 * 10**18 + allowed_recipients = recipients[:1] + + add_allowed_recipient_by_motion( + add_allowed_recipient_evm_script_factory, + allowed_recipients[0].address, + allowed_recipients[0].title, + ) + + first_top_up_amount = [period_limit] + second_top_up_amount = [1] # just 1 wei + + allowed_recipients_registry.setLimitParameters( + period_limit, initial_period_duration, {"from": lido_contracts.aragon.agent} + ) + test_helpers.advance_chain_time_to_middle_of_the_next_period(initial_period_duration) + + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + first_top_up_amount, + ) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + second_top_up_amount, + ) + + allowed_recipients_registry.setLimitParameters( + period_limit, new_period_duration, {"from": lido_contracts.aragon.agent} + ) + + # expect it to revert because although calendar grid period has changed + # the amount spent and the limit are left intact + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + create_top_up_allowed_recipients_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + second_top_up_amount, + ) + + test_helpers.advance_chain_time_to_middle_of_the_next_period(new_period_duration) + + # when move time to time point in the next period of the new calendar period grid + # expect the spendable get renewed + top_up_allowed_recipient_by_motion( + top_up_allowed_recipients_evm_script_factory, + [r.address for r in allowed_recipients], + second_top_up_amount, + ) + + +def test_set_limit_parameters_by_aragon_agent_via_voting(lido_contracts, allowed_recipients_registry): + """Do Aragon Agent to set limit parameters to the allowed recipients registry""" + period_limit, period_duration = 100 * 10**18, 6 + + set_limit_parameters_voting_id, _ = lido_contracts.create_voting( + evm_script=evm_script.encode_call_script( + [ + ( + lido_contracts.aragon.agent.address, + lido_contracts.aragon.agent.execute.encode_input( + allowed_recipients_registry, + 0, + allowed_recipients_registry.setLimitParameters.encode_input( + period_limit, + period_duration, + ), + ), + ) + ] + ), + description="Set limit parameters", + tx_params={"from": lido_contracts.aragon.agent}, + ) + + # execute voting to add permissions to EVM script executor to create payments + lido_contracts.execute_voting(set_limit_parameters_voting_id) + + assert allowed_recipients_registry.getLimitParameters() == ( + period_limit, + period_duration, + ) diff --git a/tests/integration/test_lego_happy_path.py b/tests/integration/test_lego_happy_path.py new file mode 100644 index 00000000..c08e7c5d --- /dev/null +++ b/tests/integration/test_lego_happy_path.py @@ -0,0 +1,125 @@ +import pytest +import brownie + +import constants +from utils import evm_script + + +@pytest.mark.skip_coverage +def test_lego_easy_track_happy_path( + EVMScriptExecutor, + TopUpLegoProgram, + EasyTrack, + lido_contracts, + lego_program, + accounts, + deployer, + stranger, +): + ldo = lido_contracts.ldo + steth = lido_contracts.steth + acl = lido_contracts.aragon.acl + agent = lido_contracts.aragon.agent + voting = lido_contracts.aragon.voting + finance = lido_contracts.aragon.finance + + trusted_address = accounts[7] + + # deploy easy track + easy_track = deployer.deploy( + EasyTrack, + lido_contracts.ldo, + deployer, + constants.MIN_MOTION_DURATION, + constants.MAX_MOTIONS_LIMIT, + constants.DEFAULT_OBJECTIONS_THRESHOLD, + ) + + # deploy evm script executor + evm_script_executor = deployer.deploy(EVMScriptExecutor, lido_contracts.aragon.calls_script, easy_track) + evm_script_executor.transferOwnership(voting, {"from": deployer}) + assert evm_script_executor.owner() == voting + + # set EVM script executor in easy track + easy_track.setEVMScriptExecutor(evm_script_executor, {"from": deployer}) + + # deploy TopUpLegoProgram EVM script factory + top_up_lego_program = deployer.deploy(TopUpLegoProgram, trusted_address, finance, lego_program) + + # add TopUpLegoProgram evm script to registry + new_immediate_payment_permission = finance.address + finance.newImmediatePayment.signature[2:] + easy_track.addEVMScriptFactory(top_up_lego_program, new_immediate_payment_permission, {"from": deployer}) + evm_script_factories = easy_track.getEVMScriptFactories() + assert len(evm_script_factories) == 1 + assert evm_script_factories[0] == top_up_lego_program + + # create voting to grant permissions to EVM script executor to create new payments + add_create_payments_permissions_voting_id, _ = lido_contracts.create_voting( + evm_script=evm_script.encode_call_script( + [ + ( + acl.address, + acl.grantPermission.encode_input( + evm_script_executor, + finance, + finance.CREATE_PAYMENTS_ROLE(), + ), + ), + ] + ), + description="Grant permissions to EVMScriptExecutor to make payments", + tx_params={"from": agent}, + ) + + # execute voting to add permissions to EVM script executor to create payments + lido_contracts.execute_voting(add_create_payments_permissions_voting_id) + + # create new motion to make transfers to lego programs + ldo_amount, steth_amount, eth_amount = 10**18, 2 * 10**18, 3 * 10**18 + + tx = easy_track.createMotion( + top_up_lego_program, + evm_script.encode_calldata( + ["address[]", "uint256[]"], + [ + [ldo.address, steth.address, brownie.ZERO_ADDRESS], + [ldo_amount, steth_amount, eth_amount], + ], + ), + {"from": trusted_address}, + ) + + motions = easy_track.getMotions() + assert len(motions) == 1 + + brownie.chain.sleep(48 * 60 * 60 + 100) + + # top up agent balances + ldo.approve(agent, ldo_amount, {"from": agent}) + agent.deposit(ldo, ldo_amount, {"from": agent}) + + steth.submit(brownie.ZERO_ADDRESS, {"from": deployer, "value": "2.1 ether"}) + steth.approve(agent, "2.1 ether", {"from": deployer}) + agent.deposit(steth, steth_amount, {"from": deployer}) + + agent.deposit(brownie.ZERO_ADDRESS, eth_amount, {"from": deployer, "value": eth_amount}) + + # validate agent app has enough tokens + assert agent.balance(ldo) >= ldo_amount + assert agent.balance(steth) >= steth_amount + assert agent.balance(brownie.ZERO_ADDRESS) >= eth_amount + + assert ldo.balanceOf(lego_program) == 0 + assert steth.balanceOf(lego_program) == 0 + lego_program_balance_before = lego_program.balance() + + easy_track.enactMotion( + motions[0][0], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + + assert len(easy_track.getMotions()) == 0 + assert ldo.balanceOf(lego_program) == ldo_amount + assert abs(steth.balanceOf(lego_program) - steth_amount) <= 10 + assert lego_program.balance() - lego_program_balance_before == eth_amount diff --git a/tests/integration/test_node_operators_easy_track.py b/tests/integration/test_node_operators_easy_track.py new file mode 100644 index 00000000..5bc8bed3 --- /dev/null +++ b/tests/integration/test_node_operators_easy_track.py @@ -0,0 +1,166 @@ +import pytest +import brownie + +import constants +from utils import evm_script + + +@pytest.mark.skip_coverage +def test_node_operators_easy_track_happy_path( + IncreaseNodeOperatorStakingLimit, + EVMScriptExecutor, + EasyTrack, + accounts, + voting, + agent, + node_operators_registry, + ldo, + calls_script, + acl, + lido_contracts, + deployer, + stranger, +): + deployer = accounts[0] + + # deploy easy track + easy_track = deployer.deploy( + EasyTrack, + ldo, + deployer, + constants.MIN_MOTION_DURATION, + constants.MAX_MOTIONS_LIMIT, + constants.DEFAULT_OBJECTIONS_THRESHOLD, + ) + + # deploy evm script executor + evm_script_executor = deployer.deploy(EVMScriptExecutor, calls_script, easy_track) + evm_script_executor.transferOwnership(voting, {"from": deployer}) + assert evm_script_executor.owner() == voting + + # set EVM script executor in easy track + easy_track.setEVMScriptExecutor(evm_script_executor, {"from": deployer}) + + # deploy IncreaseNodeOperatorStakingLimit EVM script factory + increase_node_operator_staking_limit = deployer.deploy(IncreaseNodeOperatorStakingLimit, node_operators_registry) + + # add IncreaseNodeOperatorStakingLimit to registry + permissions = node_operators_registry.address + node_operators_registry.setNodeOperatorStakingLimit.signature[2:] + easy_track.addEVMScriptFactory(increase_node_operator_staking_limit, permissions, {"from": deployer}) + evm_script_factories = easy_track.getEVMScriptFactories() + assert len(evm_script_factories) == 1 + assert evm_script_factories[0] == increase_node_operator_staking_limit + + # transfer admin role to voting + easy_track.grantRole(easy_track.DEFAULT_ADMIN_ROLE(), voting, {"from": deployer}) + assert easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), voting) + easy_track.revokeRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer, {"from": deployer}) + assert not easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer) + + # create voting to grant permissions to EVM script executor to set staking limit + + add_set_staking_limit_permissions_voting_id, _ = lido_contracts.create_voting( + evm_script=evm_script.encode_call_script( + [ + ( + acl.address, + acl.grantPermission.encode_input( + evm_script_executor, + node_operators_registry, + node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE(), + ), + ), + ] + ), + description="Grant permissions to EVMScriptExecutor to set staking limits", + tx_params={"from": agent}, + ) + + lido_contracts.execute_voting(add_set_staking_limit_permissions_voting_id) + + # create vote to add test node operator + node_operator = {"name": "test_node_operator", "address": accounts[3]} + add_node_operator_calldata = node_operators_registry.addNodeOperator.encode_input( + node_operator["name"], node_operator["address"] + ) + add_node_operator_evm_script = evm_script.encode_call_script( + [ + ( + acl.address, + acl.grantPermission.encode_input( + voting, node_operators_registry, node_operators_registry.MANAGE_NODE_OPERATOR_ROLE() + ), + ), + ( + node_operators_registry.address, + add_node_operator_calldata, + ), + ] + ) + + add_node_operators_voting_id, _ = lido_contracts.create_voting( + evm_script=add_node_operator_evm_script, + description="Add node operator to registry", + tx_params={"from": agent}, + ) + + # execute vote to add test node operator + lido_contracts.execute_voting(add_node_operators_voting_id) + + # validate new node operator id + new_node_operator_id = node_operators_registry.getNodeOperatorsCount() - 1 + new_node_operator = node_operators_registry.getNodeOperator(new_node_operator_id, True) + assert new_node_operator[0] # active + assert new_node_operator[1] == node_operator["name"] # name + assert new_node_operator[2] == node_operator["address"] # rewardAddress + assert new_node_operator[3] == 0 # stakingLimit + + # add signing keys to new node operator + signing_keys = { + "pubkeys": [ + "8bb1db218877a42047b953bdc32573445a78d93383ef5fd08f79c066d4781961db4f5ab5a7cc0cf1e4cbcc23fd17f9d7", + "884b147305bcd9fce3a1cc12e8f893c6356c1780688286277656e1ba724a3fde49262c98503141c0925b344a8ccea9ca", + "952ff22cf4a5f9708d536acb2170f83c137301515df5829adc28c265373487937cc45e8f91743caba0b9ebd02b3b664f", + ], + "signatures": [ + "ad17ef7cdf0c4917aaebc067a785b049d417dda5d4dd66395b21bbd50781d51e28ee750183eca3d32e1f57b324049a06135ad07d1aa243368bca9974e25233f050e0d6454894739f87faace698b90ea65ee4baba2758772e09fec4f1d8d35660", + "9794e7871dc766c2139f9476234bc29784e13b51e859445044d2a5a9df8bc072d9c51c51ee69490ce37bdfc7cf899af2166b0710d620a87398d5ec7da06c9f7eb27f1d729973efd60052dbd4cb7f43ff6b141af4d0a0a980b60f663f39bf7844", + "90111fb6944ff8b56eb0858c1deb91f41c8c631573f4c821663d7079e5e78903d67fa1c4a4ed358378f16a2b7ec524c5196b1a1eae35b01dca1df74535f45d6bd1960164a41425b2a289d4bb5c837049acf5871a0ed23598df42f6234276f6e2", + ], + } + + node_operators_registry.addSigningKeysOperatorBH( + new_node_operator_id, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": node_operator["address"]}, + ) + + # validate that signing keys have been added + new_node_operator = node_operators_registry.getNodeOperator(new_node_operator_id, True) + assert new_node_operator[5] == len(signing_keys["pubkeys"]) # totalSigningKeys + assert new_node_operator[6] == 0 # usedSigningKeys + + # create new motion to increase staking limit + tx = easy_track.createMotion( + increase_node_operator_staking_limit, + evm_script.encode_calldata(["uint256", "uint256"], [new_node_operator_id, 3]), + {"from": node_operator["address"]}, + ) + motions = easy_track.getMotions() + assert len(motions) == 1 + + brownie.chain.sleep(easy_track.motionDuration() + 100) + + easy_track.enactMotion( + motions[0][0], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + + # validate that motion was executed correctly + motions = easy_track.getMotions() + assert len(motions) == 0 + new_node_operator = node_operators_registry.getNodeOperator(new_node_operator_id, True) + assert new_node_operator[3] == 3 # stakingLimit diff --git a/tests/integration/test_reward_programs_happy_path.py b/tests/integration/test_reward_programs_happy_path.py new file mode 100644 index 00000000..6fb2bbcd --- /dev/null +++ b/tests/integration/test_reward_programs_happy_path.py @@ -0,0 +1,178 @@ +import pytest +import brownie +import constants + +from utils import evm_script + + +@pytest.mark.skip_coverage +def test_reward_programs_easy_track( + stranger, + agent, + voting, + finance, + ldo, + calls_script, + acl, + EasyTrack, + EVMScriptExecutor, + RewardProgramsRegistry, + TopUpRewardPrograms, + AddRewardProgram, + RemoveRewardProgram, + lido_contracts, + deployer, + accounts, +): + reward_program = accounts[5] + reward_program_title = "New Reward Program" + trusted_address = accounts[7] + + # deploy easy track + easy_track = deployer.deploy( + EasyTrack, + ldo, + deployer, + constants.MIN_MOTION_DURATION, + constants.MAX_MOTIONS_LIMIT, + constants.DEFAULT_OBJECTIONS_THRESHOLD, + ) + + # deploy evm script executor + evm_script_executor = deployer.deploy(EVMScriptExecutor, calls_script, easy_track) + evm_script_executor.transferOwnership(voting, {"from": deployer}) + assert evm_script_executor.owner() == voting + + # set EVM script executor in easy track + easy_track.setEVMScriptExecutor(evm_script_executor, {"from": deployer}) + + # deploy RewardProgramsRegistry + reward_programs_registry = deployer.deploy( + RewardProgramsRegistry, + voting, + [voting, evm_script_executor], + [voting, evm_script_executor], + ) + + # deploy TopUpRewardProgram EVM script factory + top_up_reward_programs = deployer.deploy( + TopUpRewardPrograms, + trusted_address, + reward_programs_registry, + finance, + ldo, + ) + + # add TopUpRewardProgram EVM script factory to easy track + new_immediate_payment_permission = finance.address + finance.newImmediatePayment.signature[2:] + easy_track.addEVMScriptFactory(top_up_reward_programs, new_immediate_payment_permission, {"from": deployer}) + + # deploy AddRewardProgram EVM script factory + add_reward_program = deployer.deploy(AddRewardProgram, trusted_address, reward_programs_registry) + + # add AddRewardProgram EVM script factory to easy track + add_reward_program_permission = ( + reward_programs_registry.address + reward_programs_registry.addRewardProgram.signature[2:] + ) + easy_track.addEVMScriptFactory(add_reward_program, add_reward_program_permission, {"from": deployer}) + + # deploy RemoveRewardProgram EVM script factory + remove_reward_program = deployer.deploy(RemoveRewardProgram, trusted_address, reward_programs_registry) + + # add RemoveRewardProgram EVM script factory to easy track + remove_reward_program_permission = ( + reward_programs_registry.address + reward_programs_registry.removeRewardProgram.signature[2:] + ) + easy_track.addEVMScriptFactory(remove_reward_program, remove_reward_program_permission, {"from": deployer}) + + # transfer admin role to voting + easy_track.grantRole(easy_track.DEFAULT_ADMIN_ROLE(), voting, {"from": deployer}) + assert easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), voting) + easy_track.revokeRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer, {"from": deployer}) + assert not easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer) + + # create voting to grant permissions to EVM script executor to create new payments + add_create_payments_permissions_voting_id, _ = lido_contracts.create_voting( + evm_script=evm_script.encode_call_script( + [ + ( + acl.address, + acl.grantPermission.encode_input( + evm_script_executor, + finance, + finance.CREATE_PAYMENTS_ROLE(), + ), + ), + ] + ), + description="Grant permissions to EVMScriptExecutor to make payments", + tx_params={"from": agent}, + ) + + # execute voting to add permissions to EVM script executor to create payments + lido_contracts.execute_voting(add_create_payments_permissions_voting_id) + + # create new motion to add reward program + tx = easy_track.createMotion( + add_reward_program, + evm_script.encode_calldata(["address", "string"], [reward_program.address, reward_program_title]), + {"from": trusted_address}, + ) + + motions = easy_track.getMotions() + assert len(motions) == 1 + + brownie.chain.sleep(48 * 60 * 60 + 100) + + easy_track.enactMotion( + motions[0][0], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + assert len(easy_track.getMotions()) == 0 + + reward_programs = reward_programs_registry.getRewardPrograms() + assert len(reward_programs) == 1 + assert reward_programs[0] == reward_program + + # create new motion to top up reward program + tx = easy_track.createMotion( + top_up_reward_programs, + evm_script.encode_calldata(["address[]", "uint256[]"], [[reward_program.address], [int(5e18)]]), + {"from": trusted_address}, + ) + motions = easy_track.getMotions() + assert len(motions) == 1 + + brownie.chain.sleep(48 * 60 * 60 + 100) + + assert ldo.balanceOf(reward_program) == 0 + + easy_track.enactMotion( + motions[0][0], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + + assert len(easy_track.getMotions()) == 0 + assert ldo.balanceOf(reward_program) == 5e18 + + # create new motion to remove reward program + tx = easy_track.createMotion( + remove_reward_program, + evm_script.encode_calldata(["address"], [reward_program.address]), + {"from": trusted_address}, + ) + + motions = easy_track.getMotions() + assert len(motions) == 1 + + brownie.chain.sleep(48 * 60 * 60 + 100) + + easy_track.enactMotion( + motions[0][0], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + assert len(easy_track.getMotions()) == 0 + assert len(reward_programs_registry.getRewardPrograms()) == 0 diff --git a/tests/integration_test.py b/tests/integration_test.py deleted file mode 100644 index f1262b6b..00000000 --- a/tests/integration_test.py +++ /dev/null @@ -1,482 +0,0 @@ -import sys -import pytest -import constants -from brownie.network import chain -from brownie import ( - EasyTrack, - EVMScriptExecutor, - accounts, - ZERO_ADDRESS, - reverts, - history, -) -from eth_abi import encode_single -from utils.evm_script import encode_call_script - -from utils.lido import create_voting, execute_voting - - -@pytest.mark.skip_coverage -def test_node_operators_easy_track( - stranger, - voting, - agent, - ldo_holders, - node_operators_registry, - ldo, - calls_script, - acl, - IncreaseNodeOperatorStakingLimit, -): - deployer = accounts[0] - - # deploy easy track - easy_track = deployer.deploy( - EasyTrack, - ldo, - deployer, - constants.MIN_MOTION_DURATION, - constants.MAX_MOTIONS_LIMIT, - constants.DEFAULT_OBJECTIONS_THRESHOLD, - ) - - # deploy evm script executor - evm_script_executor = deployer.deploy(EVMScriptExecutor, calls_script, easy_track) - evm_script_executor.transferOwnership(voting, {"from": deployer}) - assert evm_script_executor.owner() == voting - - # set EVM script executor in easy track - easy_track.setEVMScriptExecutor(evm_script_executor, {"from": deployer}) - - # deploy IncreaseNodeOperatorStakingLimit EVM script factory - increase_node_operator_staking_limit = deployer.deploy( - IncreaseNodeOperatorStakingLimit, node_operators_registry - ) - - # add IncreaseNodeOperatorStakingLimit to registry - permissions = ( - node_operators_registry.address - + node_operators_registry.setNodeOperatorStakingLimit.signature[2:] - ) - easy_track.addEVMScriptFactory( - increase_node_operator_staking_limit, permissions, {"from": deployer} - ) - evm_script_factories = easy_track.getEVMScriptFactories() - assert len(evm_script_factories) == 1 - assert evm_script_factories[0] == increase_node_operator_staking_limit - - # transfer admin role to voting - easy_track.grantRole(easy_track.DEFAULT_ADMIN_ROLE(), voting, {"from": deployer}) - assert easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), voting) - easy_track.revokeRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer, {"from": deployer}) - assert not easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer) - - # create voting to grant permissions to EVM script executor to set staking limit - - add_set_staking_limit_permissions_voting_id, _ = create_voting( - encode_call_script( - [ - ( - acl.address, - acl.grantPermission.encode_input( - evm_script_executor, - node_operators_registry, - node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE(), - ), - ), - ] - ), - "Grant permissions to EVMScriptExecutor to set staking limits", - {"from": agent}, - ) - - execute_voting(add_set_staking_limit_permissions_voting_id) - - # create vote to add test node operator - node_operator = {"name": "test_node_operator", "address": accounts[3]} - add_node_operator_calldata = node_operators_registry.addNodeOperator.encode_input( - node_operator["name"], node_operator["address"] - ) - add_node_operator_evm_script = encode_call_script( - [(node_operators_registry.address, add_node_operator_calldata)] - ) - - add_node_operators_voting_id, _ = create_voting( - add_node_operator_evm_script, "Add node operator to registry", {"from": agent} - ) - # execute vote to add test node operator - execute_voting(add_node_operators_voting_id) - - # validate new node operator id - new_node_operator_id = node_operators_registry.getActiveNodeOperatorsCount() - 1 - new_node_operator = node_operators_registry.getNodeOperator( - new_node_operator_id, True - ) - assert new_node_operator[0] # active - assert new_node_operator[1] == node_operator["name"] # name - assert new_node_operator[2] == node_operator["address"] # rewardAddress - assert new_node_operator[3] == 0 # stakingLimit - - # add signing keys to new node operator - signing_keys = { - "pubkeys": [ - "8bb1db218877a42047b953bdc32573445a78d93383ef5fd08f79c066d4781961db4f5ab5a7cc0cf1e4cbcc23fd17f9d7", - "884b147305bcd9fce3a1cc12e8f893c6356c1780688286277656e1ba724a3fde49262c98503141c0925b344a8ccea9ca", - "952ff22cf4a5f9708d536acb2170f83c137301515df5829adc28c265373487937cc45e8f91743caba0b9ebd02b3b664f", - ], - "signatures": [ - "ad17ef7cdf0c4917aaebc067a785b049d417dda5d4dd66395b21bbd50781d51e28ee750183eca3d32e1f57b324049a06135ad07d1aa243368bca9974e25233f050e0d6454894739f87faace698b90ea65ee4baba2758772e09fec4f1d8d35660", - "9794e7871dc766c2139f9476234bc29784e13b51e859445044d2a5a9df8bc072d9c51c51ee69490ce37bdfc7cf899af2166b0710d620a87398d5ec7da06c9f7eb27f1d729973efd60052dbd4cb7f43ff6b141af4d0a0a980b60f663f39bf7844", - "90111fb6944ff8b56eb0858c1deb91f41c8c631573f4c821663d7079e5e78903d67fa1c4a4ed358378f16a2b7ec524c5196b1a1eae35b01dca1df74535f45d6bd1960164a41425b2a289d4bb5c837049acf5871a0ed23598df42f6234276f6e2", - ], - } - - node_operators_registry.addSigningKeysOperatorBH( - new_node_operator_id, - len(signing_keys["pubkeys"]), - "0x" + "".join(signing_keys["pubkeys"]), - "0x" + "".join(signing_keys["signatures"]), - {"from": node_operator["address"]}, - ) - - # validate that signing keys have been added - new_node_operator = node_operators_registry.getNodeOperator( - new_node_operator_id, True - ) - assert new_node_operator[5] == len(signing_keys["pubkeys"]) # totalSigningKeys - assert new_node_operator[6] == 0 # usedSigningKeys - - # create new motion to increase staking limit - tx = easy_track.createMotion( - increase_node_operator_staking_limit, - "0x" + encode_single("(uint256,uint256)", [new_node_operator_id, 3]).hex(), - {"from": node_operator["address"]}, - ) - motions = easy_track.getMotions() - assert len(motions) == 1 - - chain.sleep(48 * 60 * 60 + 100) - - easy_track.enactMotion( - motions[0][0], - tx.events["MotionCreated"]["_evmScriptCallData"], - {"from": stranger}, - ) - - # validate that motion was executed correctly - motions = easy_track.getMotions() - assert len(motions) == 0 - new_node_operator = node_operators_registry.getNodeOperator( - new_node_operator_id, True - ) - assert new_node_operator[3] == 3 # stakingLimit - - -@pytest.mark.skip_coverage -def test_reward_programs_easy_track( - stranger, - agent, - voting, - finance, - ldo, - ldo_holders, - calls_script, - acl, - RewardProgramsRegistry, - TopUpRewardPrograms, - AddRewardProgram, - RemoveRewardProgram, -): - deployer = accounts[0] - reward_program = accounts[5] - reward_program_title = "New Reward Program" - trusted_address = accounts[7] - - # deploy easy track - easy_track = deployer.deploy( - EasyTrack, - ldo, - deployer, - constants.MIN_MOTION_DURATION, - constants.MAX_MOTIONS_LIMIT, - constants.DEFAULT_OBJECTIONS_THRESHOLD, - ) - - # deploy evm script executor - evm_script_executor = deployer.deploy(EVMScriptExecutor, calls_script, easy_track) - evm_script_executor.transferOwnership(voting, {"from": deployer}) - assert evm_script_executor.owner() == voting - - # set EVM script executor in easy track - easy_track.setEVMScriptExecutor(evm_script_executor, {"from": deployer}) - - # deploy RewardProgramsRegistry - reward_programs_registry = deployer.deploy( - RewardProgramsRegistry, - voting, - [voting, evm_script_executor], - [voting, evm_script_executor], - ) - - # deploy TopUpRewardProgram EVM script factory - top_up_reward_programs = deployer.deploy( - TopUpRewardPrograms, - trusted_address, - reward_programs_registry, - finance, - ldo, - ) - - # add TopUpRewardProgram EVM script factory to easy track - new_immediate_payment_permission = ( - finance.address + finance.newImmediatePayment.signature[2:] - ) - easy_track.addEVMScriptFactory( - top_up_reward_programs, new_immediate_payment_permission, {"from": deployer} - ) - - # deploy AddRewardProgram EVM script factory - add_reward_program = deployer.deploy( - AddRewardProgram, trusted_address, reward_programs_registry - ) - - # add AddRewardProgram EVM script factory to easy track - add_reward_program_permission = ( - reward_programs_registry.address - + reward_programs_registry.addRewardProgram.signature[2:] - ) - easy_track.addEVMScriptFactory( - add_reward_program, add_reward_program_permission, {"from": deployer} - ) - - # deploy RemoveRewardProgram EVM script factory - remove_reward_program = deployer.deploy( - RemoveRewardProgram, trusted_address, reward_programs_registry - ) - - # add RemoveRewardProgram EVM script factory to easy track - remove_reward_program_permission = ( - reward_programs_registry.address - + reward_programs_registry.removeRewardProgram.signature[2:] - ) - easy_track.addEVMScriptFactory( - remove_reward_program, remove_reward_program_permission, {"from": deployer} - ) - - # transfer admin role to voting - easy_track.grantRole(easy_track.DEFAULT_ADMIN_ROLE(), voting, {"from": deployer}) - assert easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), voting) - easy_track.revokeRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer, {"from": deployer}) - assert not easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer) - - # create voting to grant permissions to EVM script executor to create new payments - - add_create_payments_permissions_voting_id, _ = create_voting( - encode_call_script( - [ - ( - acl.address, - acl.grantPermission.encode_input( - evm_script_executor, - finance, - finance.CREATE_PAYMENTS_ROLE(), - ), - ), - ] - ), - "Grant permissions to EVMScriptExecutor to make payments", - {"from": agent}, - ) - - # execute voting to add permissions to EVM script executor to create payments - execute_voting(add_create_payments_permissions_voting_id) - - # create new motion to add reward program - tx = easy_track.createMotion( - add_reward_program, - encode_single( - "(address,string)", [reward_program.address, reward_program_title] - ), - {"from": trusted_address}, - ) - - motions = easy_track.getMotions() - assert len(motions) == 1 - - chain.sleep(48 * 60 * 60 + 100) - - easy_track.enactMotion( - motions[0][0], - tx.events["MotionCreated"]["_evmScriptCallData"], - {"from": stranger}, - ) - assert len(easy_track.getMotions()) == 0 - - reward_programs = reward_programs_registry.getRewardPrograms() - assert len(reward_programs) == 1 - assert reward_programs[0] == reward_program - - # create new motion to top up reward program - tx = easy_track.createMotion( - top_up_reward_programs, - encode_single("(address[],uint256[])", [[reward_program.address], [int(5e18)]]), - {"from": trusted_address}, - ) - motions = easy_track.getMotions() - assert len(motions) == 1 - - chain.sleep(48 * 60 * 60 + 100) - - assert ldo.balanceOf(reward_program) == 0 - - easy_track.enactMotion( - motions[0][0], - tx.events["MotionCreated"]["_evmScriptCallData"], - {"from": stranger}, - ) - - assert len(easy_track.getMotions()) == 0 - assert ldo.balanceOf(reward_program) == 5e18 - - # create new motion to remove reward program - tx = easy_track.createMotion( - remove_reward_program, - encode_single("(address)", [reward_program.address]), - {"from": trusted_address}, - ) - - motions = easy_track.getMotions() - assert len(motions) == 1 - - chain.sleep(48 * 60 * 60 + 100) - - easy_track.enactMotion( - motions[0][0], - tx.events["MotionCreated"]["_evmScriptCallData"], - {"from": stranger}, - ) - assert len(easy_track.getMotions()) == 0 - assert len(reward_programs_registry.getRewardPrograms()) == 0 - - -@pytest.mark.skip_coverage -def test_lego_easy_track( - stranger, - agent, - finance, - ldo, - steth, - lego_program, - voting, - ldo_holders, - calls_script, - acl, - TopUpLegoProgram, -): - deployer = accounts[0] - trusted_address = accounts[7] - - # deploy easy track - easy_track = deployer.deploy( - EasyTrack, - ldo, - deployer, - constants.MIN_MOTION_DURATION, - constants.MAX_MOTIONS_LIMIT, - constants.DEFAULT_OBJECTIONS_THRESHOLD, - ) - - # deploy evm script executor - evm_script_executor = deployer.deploy(EVMScriptExecutor, calls_script, easy_track) - evm_script_executor.transferOwnership(voting, {"from": deployer}) - assert evm_script_executor.owner() == voting - - # set EVM script executor in easy track - easy_track.setEVMScriptExecutor(evm_script_executor, {"from": deployer}) - - # deploy TopUpLegoProgram EVM script factory - top_up_lego_program = deployer.deploy( - TopUpLegoProgram, trusted_address, finance, lego_program - ) - - # add TopUpLegoProgram evm script to registry - new_immediate_payment_permission = ( - finance.address + finance.newImmediatePayment.signature[2:] - ) - easy_track.addEVMScriptFactory( - top_up_lego_program, new_immediate_payment_permission, {"from": deployer} - ) - evm_script_factories = easy_track.getEVMScriptFactories() - assert len(evm_script_factories) == 1 - assert evm_script_factories[0] == top_up_lego_program - - # create voting to grant permissions to EVM script executor to create new payments - add_create_payments_permissions_voting_id, _ = create_voting( - encode_call_script( - [ - ( - acl.address, - acl.grantPermission.encode_input( - evm_script_executor, - finance, - finance.CREATE_PAYMENTS_ROLE(), - ), - ), - ] - ), - "Grant permissions to EVMScriptExecutor to make payments", - {"from": agent}, - ) - - # execute voting to add permissions to EVM script executor to create payments - execute_voting(add_create_payments_permissions_voting_id) - - # create new motion to make transfers to lego programs - ldo_amount, steth_amount, eth_amount = 10 ** 18, 2 * 10 ** 18, 3 * 10 ** 18 - - tx = easy_track.createMotion( - top_up_lego_program, - encode_single( - "(address[],uint256[])", - [ - [ldo.address, steth.address, ZERO_ADDRESS], - [ldo_amount, steth_amount, eth_amount], - ], - ), - {"from": trusted_address}, - ) - - motions = easy_track.getMotions() - assert len(motions) == 1 - - chain.sleep(48 * 60 * 60 + 100) - - # top up agent balances - ldo.approve(agent, ldo_amount, {"from": agent}) - agent.deposit(ldo, ldo_amount, {"from": agent}) - - steth.submit(ZERO_ADDRESS, {"from": deployer, "value": "2.1 ether"}) - steth.approve(agent, "2.1 ether", {"from": deployer}) - agent.deposit(steth, steth_amount, {"from": deployer}) - - agent.deposit(ZERO_ADDRESS, eth_amount, {"from": deployer, "value": eth_amount}) - - # validate agent app has enough tokens - assert agent.balance(ldo) >= ldo_amount - assert agent.balance(steth) >= steth_amount - assert agent.balance(ZERO_ADDRESS) >= eth_amount - - assert ldo.balanceOf(lego_program) == 0 - assert steth.balanceOf(lego_program) == 0 - assert lego_program.balance() == 100 * 10 ** 18 - - easy_track.enactMotion( - motions[0][0], - tx.events["MotionCreated"]["_evmScriptCallData"], - {"from": stranger}, - ) - - assert len(easy_track.getMotions()) == 0 - assert ldo.balanceOf(lego_program) == ldo_amount - assert abs(steth.balanceOf(lego_program) - steth_amount) <= 10 - assert lego_program.balance() == 103 * 10 ** 18 diff --git a/tests/libraries/test_bytes_utils.py b/tests/libraries/test_bytes_utils.py index 6681bd50..600f0d70 100644 --- a/tests/libraries/test_bytes_utils.py +++ b/tests/libraries/test_bytes_utils.py @@ -36,7 +36,7 @@ def uint32_at_testcases(owner, request): (one, 0, 1), (zero, 0, 0), (empty, 0, 0), - (max_value, 0, 2 ** 32 - 1), + (max_value, 0, 2**32 - 1), (long_word, 3, 16), ][request.param] @@ -53,8 +53,8 @@ def uint256_at_testcases(owner, request): (one, 0, 1), (zero, 0, 0), (empty, 0, 0), - (max_value, 0, 2 ** 256 - 1), - (long_word, 4, 2 ** 256 - 1), + (max_value, 0, 2**256 - 1), + (long_word, 4, 2**256 - 1), ][request.param] diff --git a/tests/libraries/test_evm_script_creator.py b/tests/libraries/test_evm_script_creator.py index 55b9e5eb..c4131054 100644 --- a/tests/libraries/test_evm_script_creator.py +++ b/tests/libraries/test_evm_script_creator.py @@ -1,5 +1,5 @@ import pytest -from eth_abi import encode_single +from eth_abi import encode from utils.evm_script import encode_call_script from brownie import reverts @@ -21,15 +21,9 @@ def test_create_evm_script_one_address_single_call( method_id = node_operators_registry_stub.setNodeOperatorStakingLimit.signature method_call_data = encode_set_node_operator_staking_limit_calldata(1, 300) expected_evm_script = encode_call_script( - [ - create_method_calldata( - node_operators_registry_stub, "setNodeOperatorStakingLimit", [1, 300] - ) - ] - ) - evm_script = evm_script_creator_wrapper.createEVMScript["address,bytes4,bytes"]( - to, method_id, method_call_data + [create_method_calldata(node_operators_registry_stub, "setNodeOperatorStakingLimit", [1, 300])] ) + evm_script = evm_script_creator_wrapper.createEVMScript["address,bytes4,bytes"](to, method_id, method_call_data) assert evm_script == expected_evm_script @@ -49,20 +43,12 @@ def test_create_evm_script_one_address_multiple_calls_same_method( ] expected_evm_script = encode_call_script( [ - create_method_calldata( - node_operators_registry_stub, "setNodeOperatorStakingLimit", [1, 300] - ), - create_method_calldata( - node_operators_registry_stub, "setNodeOperatorStakingLimit", [2, 500] - ), - create_method_calldata( - node_operators_registry_stub, "setNodeOperatorStakingLimit", [3, 600] - ), + create_method_calldata(node_operators_registry_stub, "setNodeOperatorStakingLimit", [1, 300]), + create_method_calldata(node_operators_registry_stub, "setNodeOperatorStakingLimit", [2, 500]), + create_method_calldata(node_operators_registry_stub, "setNodeOperatorStakingLimit", [3, 600]), ] ) - evm_script = evm_script_creator_wrapper.createEVMScript["address,bytes4,bytes[]"]( - to, method_id, method_call_data - ) + evm_script = evm_script_creator_wrapper.createEVMScript["address,bytes4,bytes[]"](to, method_id, method_call_data) assert evm_script == expected_evm_script @@ -115,9 +101,7 @@ def test_create_evm_script_one_address_different_methods( reward_programs_registry.removeRewardProgram.signature, ], [ - encode_add_reward_program_calldata( - reward_program_to_add.address, new_reward_program_title - ), + encode_add_reward_program_calldata(reward_program_to_add.address, new_reward_program_title), encode_remove_reward_program_calldata(reward_program_to_remove.address), ], ) @@ -183,34 +167,25 @@ def test_create_evm_script_many_addresses( ] expected_evm_script = encode_call_script( [ - create_method_calldata( - node_operators_registry_stub, "setNodeOperatorStakingLimit", [1, 300] - ), - create_method_calldata( - reward_programs_registry, "removeRewardProgram", [reward_program] - ), - create_method_calldata( - node_operators_registry_stub, "setNodeOperatorStakingLimit", [3, 600] - ), + create_method_calldata(node_operators_registry_stub, "setNodeOperatorStakingLimit", [1, 300]), + create_method_calldata(reward_programs_registry, "removeRewardProgram", [reward_program]), + create_method_calldata(node_operators_registry_stub, "setNodeOperatorStakingLimit", [3, 600]), ] ) - evm_script = evm_script_creator_wrapper.createEVMScript[ - "address[],bytes4[],bytes[]" - ](to, method_id, method_call_data) + evm_script = evm_script_creator_wrapper.createEVMScript["address[],bytes4[],bytes[]"]( + to, method_id, method_call_data + ) assert evm_script == expected_evm_script def encode_remove_reward_program_calldata(reward_program): - return "0x" + encode_single("(address)", [reward_program]).hex() + return "0x" + encode(["address"], [reward_program]).hex() def encode_add_reward_program_calldata(reward_program, title): - return "0x" + encode_single("(address,string)", [reward_program, title]).hex() + return "0x" + encode(["address", "string"], [reward_program, title]).hex() def encode_set_node_operator_staking_limit_calldata(node_operator_id, staking_limit): - return ( - "0x" - + encode_single("(uint256,uint256)", [node_operator_id, staking_limit]).hex() - ) + return "0x" + encode(["uint256", "uint256"], [node_operator_id, staking_limit]).hex() diff --git a/tests/libraries/test_evm_script_permissions.py b/tests/libraries/test_evm_script_permissions.py index 57f24724..49d4e5eb 100644 --- a/tests/libraries/test_evm_script_permissions.py +++ b/tests/libraries/test_evm_script_permissions.py @@ -9,9 +9,7 @@ def valid_permissions(request): """Returns a valid permissions value.""" zero_permission = to_bytes(ZERO_ADDRESS + "aabbccdd", "bytes") deadbeef_permission = b"\xde\xad\xbe\xef" * 6 - feedface_permission = bytes.fromhex("feedface") * 5 + bytes.fromhex( - "baddcafe" - ) # different bytes for the selector + feedface_permission = bytes.fromhex("feedface") * 5 + bytes.fromhex("baddcafe") # different bytes for the selector assert len(deadbeef_permission) == 24 @@ -47,20 +45,14 @@ def method(contract, method): @pytest.fixture(scope="module") -def node_operators_registry_stub_permissions( - create_permission, node_operators_registry_stub -): +def node_operators_registry_stub_permissions(create_permission, node_operators_registry_stub): def method(method_names): permissions = { "setNodeOperatorStakingLimit": create_permission( node_operators_registry_stub, "setNodeOperatorStakingLimit" ), - "getNodeOperator": create_permission( - node_operators_registry_stub, "getNodeOperator" - ), - "setRewardAddress": create_permission( - node_operators_registry_stub, "setRewardAddress" - ), + "getNodeOperator": create_permission(node_operators_registry_stub, "getNodeOperator"), + "setRewardAddress": create_permission(node_operators_registry_stub, "setRewardAddress"), } result = "0x" for method_name in method_names: @@ -76,9 +68,7 @@ def method(method_names): calldata = { "setNodeOperatorStakingLimit": ( node_operators_registry_stub.address, - node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input( - 1, 200 - ), + node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input(1, 200), ), "getNodeOperator": ( node_operators_registry_stub.address, @@ -104,24 +94,16 @@ def permissions_with_not_allowed_calldata( node_operators_registry_stub_calldata, ): has_all_except_one_permission = ( - node_operators_registry_stub_permissions( - ["getNodeOperator", "setRewardAddress"] - ), - node_operators_registry_stub_calldata( - ["setNodeOperatorStakingLimit", "getNodeOperator", "getNodeOperator"] - ), + node_operators_registry_stub_permissions(["getNodeOperator", "setRewardAddress"]), + node_operators_registry_stub_calldata(["setNodeOperatorStakingLimit", "getNodeOperator", "getNodeOperator"]), ) has_no_required_permission_one_call = ( - node_operators_registry_stub_permissions( - ["getNodeOperator", "setRewardAddress"] - ), + node_operators_registry_stub_permissions(["getNodeOperator", "setRewardAddress"]), node_operators_registry_stub_calldata(["setNodeOperatorStakingLimit"]), ) has_no_required_permission_many_calls = ( node_operators_registry_stub_permissions(["getNodeOperator"]), - node_operators_registry_stub_calldata( - ["setRewardAddress", "setNodeOperatorStakingLimit"] - ), + node_operators_registry_stub_calldata(["setRewardAddress", "setNodeOperatorStakingLimit"]), ) test_cases = [ has_all_except_one_permission, @@ -142,9 +124,7 @@ def permissions_with_allowed_calldata( ) many_permissions_many_evm_scripts = ( all_permissions, - node_operators_registry_stub_calldata( - ["setNodeOperatorStakingLimit", "setRewardAddress"] - ), + node_operators_registry_stub_calldata(["setNodeOperatorStakingLimit", "setRewardAddress"]), ) many_permissions_one_evm_script = ( all_permissions, @@ -177,17 +157,11 @@ def test_can_execute_evm_script_wrong_permissions_length( assert not evm_script_permissions_wrapper.canExecuteEVMScript("0x0011223344", b"") -def test_can_execute_evm_script_evm_script_too_short( - evm_script_permissions_wrapper, valid_permissions -): - assert not evm_script_permissions_wrapper.canExecuteEVMScript( - valid_permissions, b"" - ) +def test_can_execute_evm_script_evm_script_too_short(evm_script_permissions_wrapper, valid_permissions): + assert not evm_script_permissions_wrapper.canExecuteEVMScript(valid_permissions, b"") -def test_can_execute_evm_script_has_permissions( - evm_script_permissions_wrapper, permissions_with_allowed_calldata -): +def test_can_execute_evm_script_has_permissions(evm_script_permissions_wrapper, permissions_with_allowed_calldata): permission, calldata = permissions_with_allowed_calldata assert evm_script_permissions_wrapper.canExecuteEVMScript(permission, calldata) @@ -203,7 +177,5 @@ def test_is_valid_permissions_valid(evm_script_permissions_wrapper, valid_permis assert evm_script_permissions_wrapper.isValidPermissions(valid_permissions) -def test_is_valid_permissions_invalid( - evm_script_permissions_wrapper, invalid_permissions -): +def test_is_valid_permissions_invalid(evm_script_permissions_wrapper, invalid_permissions): assert not evm_script_permissions_wrapper.isValidPermissions(invalid_permissions) diff --git a/tests/scenario/conftest.py b/tests/scenario/conftest.py new file mode 100644 index 00000000..e5ebd8fc --- /dev/null +++ b/tests/scenario/conftest.py @@ -0,0 +1,430 @@ +import pytest +import os +import json + +from brownie import ( + chain, + AddNodeOperators, + ActivateNodeOperators, + DeactivateNodeOperators, + SetNodeOperatorNames, + SetNodeOperatorRewardAddresses, + SetVettedValidatorsLimits, + ChangeNodeOperatorManagers, + UpdateTargetValidatorLimits, + IncreaseVettedValidatorsLimit, +) +from utils import deployed_easy_track +from utils.config import get_network_name + +ENV_VOTE_ID = "VOTE_ID" +ENV_USE_DEPLOYED_CONTRACTS = "USE_DEPLOYED_CONTRACTS" + + +@pytest.fixture(scope="session") +def deployer(accounts): + return accounts[2] + + +@pytest.fixture(scope="session") +def commitee_multisig(accounts): + return accounts[2] + + +@pytest.fixture(scope="module") +def et_contracts(): + network_name = get_network_name() + return deployed_easy_track.contracts(network_name) + + +@pytest.fixture(scope="module") +def easytrack_executor(et_contracts, stranger): + def helper(creator, factory, calldata): + tx = et_contracts.easy_track.createMotion( + factory, + calldata, + {"from": creator}, + ) + + print("creation costs: ", tx.gas_used) + + motions = et_contracts.easy_track.getMotions() + + chain.sleep(72 * 60 * 60 + 100) + + etx = et_contracts.easy_track.enactMotion( + motions[-1][0], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + print("enactment costs: ", etx.gas_used) + + return helper + + +@pytest.fixture(scope="module") +def easytrack_pair_executor_with_collision(et_contracts, stranger): + def helper(revert, motion_pair): + txs = [] + assert len(motion_pair) == 2 + for ind in [0, 1]: + (creator, factory, calldata) = motion_pair[ind] + txs.append( + et_contracts.easy_track.createMotion( + factory, + calldata, + {"from": creator}, + ) + ) + print("creation costs: ", txs[ind].gas_used) + + motions = et_contracts.easy_track.getMotions() + chain.sleep(72 * 60 * 60 + 100) + + etx = et_contracts.easy_track.enactMotion( + motions[-2][0], + txs[-2].events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + print("enactment costs: ", etx.gas_used) + + with revert: + etx = et_contracts.easy_track.enactMotion( + motions[-1][0], + txs[-1].events["MotionCreated"]["_evmScriptCallData"], + {"from": stranger}, + ) + print("enactment costs: ", etx.gas_used) + + et_contracts.easy_track.cancelMotion(motions[-1][0], {"from": creator}) + + return helper + + +@pytest.fixture(scope="session") +def vote_id_from_env(): + if os.getenv(ENV_VOTE_ID): + try: + vote_id = int(os.getenv(ENV_VOTE_ID)) + return vote_id + except: + return None + return None + + +@pytest.fixture(scope="session") +def use_deployed_contracts_from_env(): + return True if os.getenv(ENV_USE_DEPLOYED_CONTRACTS) else False + + +@pytest.fixture(scope="session") +def deployed_artifact(): + network_name = get_network_name() + file_name = f"deployed-{network_name}.json" + + try: + f = open(file_name) + return json.load(f) + except: + pass + + +@pytest.fixture(scope="module", autouse=True) +def execute_vote_from_env(vote_id_from_env, lido_contracts): + if vote_id_from_env: + print(f"VOTE_ID env var is set, executing voting {vote_id_from_env}") + lido_contracts.execute_voting(vote_id_from_env) + + +@pytest.fixture(scope="module") +def add_node_operators_factory( + et_contracts, + voting, + commitee_multisig, + simple_dvt, + deployer, + acl, + vote_id_from_env, + deployed_artifact, + use_deployed_contracts_from_env, + steth, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return AddNodeOperators.at(deployed_artifact["AddNodeOperators"]["address"]) + + factory = AddNodeOperators.deploy(commitee_multisig, simple_dvt, acl, steth, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + + add_node_operators_permissions = ( + simple_dvt.address + + simple_dvt.addNodeOperator.signature[2:] + + acl.address[2:] + + acl.grantPermissionP.signature[2:] + ) + et_contracts.easy_track.addEVMScriptFactory(factory, add_node_operators_permissions, {"from": voting}) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def activate_node_operators_factory( + et_contracts, + voting, + commitee_multisig, + simple_dvt, + deployer, + acl, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, +): + print(vote_id_from_env) + if vote_id_from_env or use_deployed_contracts_from_env: + return ActivateNodeOperators.at(deployed_artifact["ActivateNodeOperators"]["address"]) + + factory = ActivateNodeOperators.deploy(commitee_multisig, simple_dvt, acl, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + + activate_node_operators_permissions = ( + simple_dvt.address + + simple_dvt.activateNodeOperator.signature[2:] + + acl.address[2:] + + acl.grantPermissionP.signature[2:] + ) + et_contracts.easy_track.addEVMScriptFactory( + factory, + activate_node_operators_permissions, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def deactivate_node_operators_factory( + et_contracts, + voting, + commitee_multisig, + simple_dvt, + deployer, + acl, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return DeactivateNodeOperators.at(deployed_artifact["DeactivateNodeOperators"]["address"]) + + factory = DeactivateNodeOperators.deploy(commitee_multisig, simple_dvt, acl, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + + deactivate_node_operators_permissions = ( + simple_dvt.address + + simple_dvt.deactivateNodeOperator.signature[2:] + + acl.address[2:] + + acl.revokePermission.signature[2:] + ) + et_contracts.easy_track.addEVMScriptFactory( + factory, + deactivate_node_operators_permissions, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def set_node_operator_name_factory( + et_contracts, + voting, + commitee_multisig, + simple_dvt, + deployer, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return SetNodeOperatorNames.at(deployed_artifact["SetNodeOperatorNames"]["address"]) + + factory = SetNodeOperatorNames.deploy(commitee_multisig, simple_dvt, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + + set_node_operator_name_permissions = simple_dvt.address + simple_dvt.setNodeOperatorName.signature[2:] + et_contracts.easy_track.addEVMScriptFactory( + factory, + set_node_operator_name_permissions, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def set_node_operator_reward_address_factory( + et_contracts, + voting, + commitee_multisig, + simple_dvt, + deployer, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, + steth, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return SetNodeOperatorRewardAddresses.at(deployed_artifact["SetNodeOperatorRewardAddresses"]["address"]) + + factory = SetNodeOperatorRewardAddresses.deploy(commitee_multisig, simple_dvt, steth, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + + set_node_operator_name_permissions = simple_dvt.address + simple_dvt.setNodeOperatorRewardAddress.signature[2:] + et_contracts.easy_track.addEVMScriptFactory( + factory, + set_node_operator_name_permissions, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def set_vetted_validators_limit_factory( + et_contracts, + voting, + simple_dvt, + deployer, + commitee_multisig, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return SetVettedValidatorsLimits.at(deployed_artifact["SetVettedValidatorsLimits"]["address"]) + + factory = SetVettedValidatorsLimits.deploy(commitee_multisig, simple_dvt, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + + set_vetted_validators_limit_permission = simple_dvt.address + simple_dvt.setNodeOperatorStakingLimit.signature[2:] + et_contracts.easy_track.addEVMScriptFactory( + factory, + set_vetted_validators_limit_permission, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def increase_vetted_validators_limit_factory( + et_contracts, + voting, + simple_dvt, + deployer, + commitee_multisig, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return IncreaseVettedValidatorsLimit.at(deployed_artifact["IncreaseVettedValidatorsLimit"]["address"]) + + factory = IncreaseVettedValidatorsLimit.deploy(simple_dvt, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + + increase_vetted_validators_limit_permission = ( + simple_dvt.address + simple_dvt.setNodeOperatorStakingLimit.signature[2:] + ) + et_contracts.easy_track.addEVMScriptFactory( + factory, + increase_vetted_validators_limit_permission, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def change_node_operator_manager_factory( + et_contracts, + voting, + simple_dvt, + deployer, + commitee_multisig, + acl, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return ChangeNodeOperatorManagers.at(deployed_artifact["ChangeNodeOperatorManagers"]["address"]) + + factory = ChangeNodeOperatorManagers.deploy(commitee_multisig, simple_dvt, acl, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + assert factory.acl() == acl + + change_node_operator_manager_permission = ( + acl.address + acl.revokePermission.signature[2:] + acl.address[2:] + acl.grantPermissionP.signature[2:] + ) + et_contracts.easy_track.addEVMScriptFactory( + factory, + change_node_operator_manager_permission, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory + + +@pytest.fixture(scope="module") +def update_tareget_validator_limits_factory( + et_contracts, + voting, + simple_dvt, + deployer, + commitee_multisig, + deployed_artifact, + vote_id_from_env, + use_deployed_contracts_from_env, +): + if vote_id_from_env or use_deployed_contracts_from_env: + return UpdateTargetValidatorLimits.at(deployed_artifact["UpdateTargetValidatorLimits"]["address"]) + + factory = UpdateTargetValidatorLimits.deploy(commitee_multisig, simple_dvt, {"from": deployer}) + assert factory.nodeOperatorsRegistry() == simple_dvt + assert factory.trustedCaller() == commitee_multisig + + update_tareget_validators_limits_permission = ( + simple_dvt.address + simple_dvt.updateTargetValidatorsLimits.signature[2:] + ) + et_contracts.easy_track.addEVMScriptFactory( + factory, + update_tareget_validators_limits_permission, + {"from": voting}, + ) + evm_script_factories = et_contracts.easy_track.getEVMScriptFactories() + assert evm_script_factories[-1] == factory + + return factory diff --git a/tests/scenario/test_dvt_scenario.py b/tests/scenario/test_dvt_scenario.py new file mode 100644 index 00000000..b975b1d4 --- /dev/null +++ b/tests/scenario/test_dvt_scenario.py @@ -0,0 +1,368 @@ +import pytest +from eth_abi import encode +from brownie import web3, interface +from utils.evm_script import encode_call_script +from utils.permission_parameters import Op, Param, encode_permission_params + +clusters = [ + { + "address": "0x000000000000000000000000000000000000{:04}".format(i), + "manager": "0x000000000000000000000000000000000000{:04}".format(i), + "name": "Cluster " + str(i), + } + for i in range(1, 37) +] + +signing_keys = { + "pubkeys": [ + "8bb1db218877a42047b953bdc32573445a78d93383ef5fd08f79c066d4781961db4f5ab5a7cc0cf1e4cbcc23fd17f9d7", + "884b147305bcd9fce3a1cc12e8f893c6356c1780688286277656e1ba724a3fde49262c98503141c0925b344a8ccea9ca", + "952ff22cf4a5f9708d536acb2170f83c137301515df5829adc28c265373487937cc45e8f91743caba0b9ebd02b3b664f", + ], + "signatures": [ + "ad17ef7cdf0c4917aaebc067a785b049d417dda5d4dd66395b21bbd50781d51e28ee750183eca3d32e1f57b324049a06135ad07d1aa243368bca9974e25233f050e0d6454894739f87faace698b90ea65ee4baba2758772e09fec4f1d8d35660", + "9794e7871dc766c2139f9476234bc29784e13b51e859445044d2a5a9df8bc072d9c51c51ee69490ce37bdfc7cf899af2166b0710d620a87398d5ec7da06c9f7eb27f1d729973efd60052dbd4cb7f43ff6b141af4d0a0a980b60f663f39bf7844", + "90111fb6944ff8b56eb0858c1deb91f41c8c631573f4c821663d7079e5e78903d67fa1c4a4ed358378f16a2b7ec524c5196b1a1eae35b01dca1df74535f45d6bd1960164a41425b2a289d4bb5c837049acf5871a0ed23598df42f6234276f6e2", + ], +} + + +@pytest.fixture(scope="module") +def simple_dvt( + node_operators_registry, + kernel, + voting, + locator, + staking_router, + agent, + acl, +): + nor_proxy = interface.AragonAppProxy(node_operators_registry) + module_name = "simple-dvt-registry" + name = web3.keccak(text=module_name).hex() + simple_DVT_tx = kernel.newAppInstance(name, nor_proxy.implementation(), {"from": voting}) + + simple_dvt_contract = interface.NodeOperatorsRegistry(simple_DVT_tx.new_contracts[0]) + + simple_dvt_contract.initialize(locator, "0x01", 0, {"from": voting}) + + staking_router.grantRole(web3.keccak(text="STAKING_MODULE_MANAGE_ROLE").hex(), agent, {"from": agent}) + + staking_router.addStakingModule("Simple DVT", simple_dvt_contract, 10_000, 500, 500, {"from": agent}) + + acl.createPermission( + agent, + simple_dvt_contract, + web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE").hex(), + agent, + {"from": voting}, + ) + + return simple_dvt_contract + + +def test_simple_dvt_scenario( + simple_dvt, + voting, + commitee_multisig, + et_contracts, + acl, + agent, + easytrack_executor, + add_node_operators_factory, + activate_node_operators_factory, + deactivate_node_operators_factory, + set_node_operator_name_factory, + set_node_operator_reward_address_factory, + set_vetted_validators_limit_factory, + change_node_operator_manager_factory, + update_tareget_validator_limits_factory, + increase_vetted_validators_limit_factory, + stranger, +): + # Grant roles + acl.grantPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.MANAGE_NODE_OPERATOR_ROLE(), + {"from": agent}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.SET_NODE_OPERATOR_LIMIT_ROLE(), + agent, + {"from": voting}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.MANAGE_SIGNING_KEYS(), + et_contracts.evm_script_executor, + {"from": voting}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.STAKING_ROUTER_ROLE(), + agent, + {"from": voting}, + ) + + # Add clusters + add_node_operators_calldata = ( + "0x" + + encode( + ["uint256", "(string,address,address)[]"], + [ + 0, + [(cluster["name"], cluster["address"], cluster["manager"]) for cluster in clusters], + ], + ).hex() + ) + + easytrack_executor(commitee_multisig, add_node_operators_factory, add_node_operators_calldata) + + for cluster_index in range(len(clusters)): + cluster = simple_dvt.getNodeOperator(cluster_index, True) + assert cluster["active"] == True + assert cluster["name"] == clusters[cluster_index]["name"] + assert cluster["rewardAddress"] == clusters[cluster_index]["address"] + assert cluster["totalVettedValidators"] == 0 + assert cluster["totalExitedValidators"] == 0 + assert cluster["totalAddedValidators"] == 0 + assert cluster["totalDepositedValidators"] == 0 + + assert ( + simple_dvt.canPerform( + clusters[cluster_index]["manager"], + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, cluster_index)]), + ) + == True + ) + + # Deactivate node operators with ids 2,3,4 + + deactivate_node_operators_data = [] + + for cluster_index in range(2, 5): + deactivate_node_operators_data.append((cluster_index, clusters[cluster_index]["manager"])) + + deactivate_node_operators_calldata = "0x" + encode(["(uint256,address)[]"], [deactivate_node_operators_data]).hex() + + easytrack_executor( + commitee_multisig, + deactivate_node_operators_factory, + deactivate_node_operators_calldata, + ) + + for cluster_index in range(2, 5): + cluster = simple_dvt.getNodeOperator(cluster_index, True) + assert cluster["active"] == False + + assert ( + simple_dvt.canPerform( + clusters[cluster_index]["manager"], + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, cluster_index)]), + ) + == False + ) + + # Activate node operators with ids 2,3,4 + + activate_node_operators_data = [] + + for cluster_index in range(2, 5): + activate_node_operators_data.append((cluster_index, clusters[cluster_index]["manager"])) + + activate_node_operators_calldata = "0x" + encode(["(uint256,address)[]"], [activate_node_operators_data]).hex() + + easytrack_executor( + commitee_multisig, + activate_node_operators_factory, + activate_node_operators_calldata, + ) + + for cluster_index in range(2, 5): + cluster = simple_dvt.getNodeOperator(cluster_index, True) + assert cluster["active"] == True + + assert ( + simple_dvt.canPerform( + clusters[cluster_index]["manager"], + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, cluster_index)]), + ) + == True + ) + + # Set name of node operator + + set_node_operator_name_calldata = "0x" + encode(["(uint256,string)[]"], [[(6, "New Name")]]).hex() + + easytrack_executor( + commitee_multisig, + set_node_operator_name_factory, + set_node_operator_name_calldata, + ) + + cluster = simple_dvt.getNodeOperator(6, True) + assert cluster["name"] == "New Name" + + # Set reward address of node operator + new_reward_address = "0x000000000000000000000000000000000000dEaD" + set_node_operator_reward_address_calldata = ( + "0x" + encode(["(uint256,address)[]"], [[(6, new_reward_address)]]).hex() + ) + + easytrack_executor( + commitee_multisig, + set_node_operator_reward_address_factory, + set_node_operator_reward_address_calldata, + ) + + cluster = simple_dvt.getNodeOperator(6, True) + assert cluster["rewardAddress"] == new_reward_address + + # add signing keys to node operator + no_5_id = 5 + no_5 = simple_dvt.getNodeOperator(no_5_id, False) + + simple_dvt.addSigningKeysOperatorBH( + no_5_id, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": clusters[5]["manager"]}, + ) + + assert cluster["totalVettedValidators"] == 0 + + # Increase staking limit with commitee + simple_dvt.addSigningKeysOperatorBH( + no_5_id, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": clusters[5]["manager"]}, + ) + + no_6_id = 6 + no_6 = simple_dvt.getNodeOperator(no_6_id, False) + simple_dvt.addSigningKeysOperatorBH( + no_6_id, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": clusters[6]["manager"]}, + ) + + set_vetted_validators_limit_calldata = "0x" + encode(["(uint256,uint256)[]"], [[(no_5_id, 4), (no_6_id, 3)]]).hex() + easytrack_executor( + commitee_multisig, + set_vetted_validators_limit_factory, + set_vetted_validators_limit_calldata, + ) + + cluster_5 = simple_dvt.getNodeOperator(no_5_id, False) + assert cluster_5["totalVettedValidators"] == 4 + cluster_6 = simple_dvt.getNodeOperator(no_6_id, False) + assert cluster_6["totalVettedValidators"] == 3 + + # Increase staking limit with cluster + simple_dvt.addSigningKeysOperatorBH( + no_5_id, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": clusters[5]["manager"]}, + ) + + increase_vetted_validators_limit_calldata = "0x" + encode(["(uint256,uint256)"], [(no_5_id, 6)]).hex() + easytrack_executor( + clusters[5]["manager"], + increase_vetted_validators_limit_factory, + increase_vetted_validators_limit_calldata, + ) + + cluster_5 = simple_dvt.getNodeOperator(no_5_id, False) + assert cluster_5["totalVettedValidators"] == 6 + + # Update target validators limits + + update_tareget_validator_limits_calldata = ( + "0x" + encode(["(uint256,bool,uint256)[]"], [[(no_5_id, True, 1), (no_6_id, True, 10)]]).hex() + ) + easytrack_executor( + commitee_multisig, + update_tareget_validator_limits_factory, + update_tareget_validator_limits_calldata, + ) + + no_5_summary = simple_dvt.getNodeOperatorSummary(no_5_id) + no_6_summary = simple_dvt.getNodeOperatorSummary(no_6_id) + + assert no_5_summary["isTargetLimitActive"] == True + assert no_6_summary["isTargetLimitActive"] == True + assert no_5_summary["targetValidatorsCount"] == 1 + assert no_6_summary["targetValidatorsCount"] == 10 + + # Transfer cluster manager + change_node_operator_manager_calldata = ( + "0x" + + encode( + ["(uint256,address,address)[]"], + [[(no_5_id, clusters[no_5_id]["manager"], stranger.address)]], + ).hex() + ) + + easytrack_executor( + commitee_multisig, + change_node_operator_manager_factory, + change_node_operator_manager_calldata, + ) + + assert not simple_dvt.canPerform( + clusters[no_5_id]["manager"], + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, no_5_id)]), + ) + assert simple_dvt.canPerform( + stranger, + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, no_5_id)]), + ) + + # Renounce MANAGE_SIGNING_KEYS role manager + + set_permission_manager_calldata = acl.setPermissionManager.encode_input( + agent, simple_dvt, web3.keccak(text="MANAGE_SIGNING_KEYS").hex() + ) + + set_permission_manager_calldata = et_contracts.evm_script_executor.executeEVMScript.encode_input( + encode_call_script( + [ + ( + acl.address, + acl.setPermissionManager.encode_input( + agent, + simple_dvt, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + ), + ) + ] + ), + ) + + et_contracts.evm_script_executor.setEasyTrack(agent, {"from": voting}) + agent.execute( + et_contracts.evm_script_executor, + 0, + set_permission_manager_calldata, + {"from": voting}, + ) + et_contracts.evm_script_executor.setEasyTrack(et_contracts.easy_track, {"from": voting}) + + assert acl.getPermissionManager(simple_dvt, simple_dvt.MANAGE_SIGNING_KEYS()) == agent diff --git a/tests/scenario/test_dvt_scenario_collisions.py b/tests/scenario/test_dvt_scenario_collisions.py new file mode 100644 index 00000000..5d0b463a --- /dev/null +++ b/tests/scenario/test_dvt_scenario_collisions.py @@ -0,0 +1,418 @@ +import pytest +from eth_abi import encode +from brownie import reverts, web3, interface + +table = [ + { + "address": "0x000000000000000000000000000000000000{:04}".format(i), + "manager": "0x000000000000000000000000000000000000{:04}".format(i), + "name": "Table " + str(i), + } + for i in range(1, 5) +] + +signing_keys = { + "pubkeys": [ + "8bb1db218877a42047b953bdc32573445a78d93383ef5fd08f79c066d4781961db4f5ab5a7cc0cf1e4cbcc23fd17f9d7", + "884b147305bcd9fce3a1cc12e8f893c6356c1780688286277656e1ba724a3fde49262c98503141c0925b344a8ccea9ca", + "952ff22cf4a5f9708d536acb2170f83c137301515df5829adc28c265373487937cc45e8f91743caba0b9ebd02b3b664f", + ], + "signatures": [ + "ad17ef7cdf0c4917aaebc067a785b049d417dda5d4dd66395b21bbd50781d51e28ee750183eca3d32e1f57b324049a06135ad07d1aa243368bca9974e25233f050e0d6454894739f87faace698b90ea65ee4baba2758772e09fec4f1d8d35660", + "9794e7871dc766c2139f9476234bc29784e13b51e859445044d2a5a9df8bc072d9c51c51ee69490ce37bdfc7cf899af2166b0710d620a87398d5ec7da06c9f7eb27f1d729973efd60052dbd4cb7f43ff6b141af4d0a0a980b60f663f39bf7844", + "90111fb6944ff8b56eb0858c1deb91f41c8c631573f4c821663d7079e5e78903d67fa1c4a4ed358378f16a2b7ec524c5196b1a1eae35b01dca1df74535f45d6bd1960164a41425b2a289d4bb5c837049acf5871a0ed23598df42f6234276f6e2", + ], +} + +no1 = 0 +no2 = 1 +no3 = 2 +no4 = 3 + +name1 = table[no1]["name"] +name2 = table[no2]["name"] +name3 = table[no3]["name"] +name4 = table[no4]["name"] + +manager1 = table[no1]["manager"] +manager2 = table[no2]["manager"] +manager3 = table[no3]["manager"] +manager4 = table[no4]["manager"] + +address1 = table[no1]["address"] +address2 = table[no2]["address"] +address3 = table[no3]["address"] +address4 = table[no4]["address"] + + +@pytest.fixture(scope="module") +def simple_dvt( + node_operators_registry, + kernel, + voting, + locator, + staking_router, + agent, + acl, +): + nor_proxy = interface.AragonAppProxy(node_operators_registry) + module_name = "simple-dvt-registry" + name = web3.keccak(text=module_name).hex() + simple_DVT_tx = kernel.newAppInstance(name, nor_proxy.implementation(), {"from": voting}) + + simple_dvt_contract = interface.NodeOperatorsRegistry(simple_DVT_tx.new_contracts[0]) + + simple_dvt_contract.initialize(locator, "0x01", 0, {"from": voting}) + + staking_router.grantRole(web3.keccak(text="STAKING_MODULE_MANAGE_ROLE").hex(), agent, {"from": agent}) + + staking_router.addStakingModule("Simple DVT", simple_dvt_contract, 10_000, 500, 500, {"from": agent}) + + acl.createPermission( + agent, + simple_dvt_contract, + web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE").hex(), + agent, + {"from": voting}, + ) + + return simple_dvt_contract + + +def prepare_add_node_operator_calldata(count, name, address, manager): + return ( + "0x" + + encode( + ["uint256", "(string,address,address)[]"], + [count, [(name, address, manager)]], + ).hex() + ) + + +def prepare_deactivate_node_operator_calldata(operator, manager): + return "0x" + encode(["(uint256,address)[]"], [[(operator, manager)]]).hex() + + +def prepare_activate_node_operator_calldata(operator, manager): + return "0x" + encode(["(uint256,address)[]"], [[(operator, manager)]]).hex() + + +def prepare_change_node_operator_manager_calldata(operator, old_manager, new_manager): + return ( + "0x" + + encode( + ["(uint256,address,address)[]"], + [[(operator, old_manager, new_manager)]], + ).hex() + ) + + +def prepare_set_node_operator_name_calldata(operator, name): + return "0x" + encode(["(uint256,string)[]"], [[(operator, name)]]).hex() + + +def prepare_set_node_operator_reward_address_calldata(operator, address): + return "0x" + encode(["(uint256,address)[]"], [[(operator, address)]]).hex() + + +def prepare_update_target_validator_limits_calldata(id_operator, is_active, target_limits): + return "0x" + encode(["(uint256,bool,uint256)[]"], [[(id_operator, is_active, target_limits)]]).hex() + + +def prepare_set_vetted_validators_limit_calldata(id_operator, vetted_limit): + return "0x" + encode(["(uint256,uint256)[]"], [[(id_operator, vetted_limit)]]).hex() + + +def prepare_increase_vetted_validators_limit_calldata(id_operator, vetted_limit): + return "0x" + encode(["(uint256,uint256)"], [(id_operator, vetted_limit)]).hex() + + +def test_simple_dvt_scenario( + simple_dvt, + voting, + commitee_multisig, + et_contracts, + acl, + agent, + easytrack_executor, + easytrack_pair_executor_with_collision, + add_node_operators_factory, + activate_node_operators_factory, + deactivate_node_operators_factory, + set_node_operator_name_factory, + set_node_operator_reward_address_factory, + set_vetted_validators_limit_factory, + change_node_operator_manager_factory, + update_tareget_validator_limits_factory, + increase_vetted_validators_limit_factory, +): + # Grant roles + acl.grantPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.MANAGE_NODE_OPERATOR_ROLE(), + {"from": agent}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.SET_NODE_OPERATOR_LIMIT_ROLE(), + agent, + {"from": voting}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.MANAGE_SIGNING_KEYS(), + et_contracts.evm_script_executor, + {"from": voting}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.STAKING_ROUTER_ROLE(), + agent, + {"from": voting}, + ) + + # 1) AddNodeOperators - AddNodeOperators -> NODE_OPERATORS_COUNT_MISMATCH + # Add no1 address1 manager1 name1 v + # Add no1 address1 manager1 name1 x + add_node_operator_calldata = prepare_add_node_operator_calldata(0, name1, address1, manager1) + + easytrack_pair_executor_with_collision( + reverts("NODE_OPERATORS_COUNT_MISMATCH"), + [ + (commitee_multisig, add_node_operators_factory, add_node_operator_calldata), + (commitee_multisig, add_node_operators_factory, add_node_operator_calldata), + ], + ) + + # -) deactivate no1 + deactivate_node_operator_calldata = prepare_deactivate_node_operator_calldata(no1, manager1) + + easytrack_executor( + commitee_multisig, + deactivate_node_operators_factory, + deactivate_node_operator_calldata, + ) + + # 2) ActivateNodeOperators - AddNodeOperators -> MANAGER_ALREADY_HAS_ROLE + # Activate no1 address1 manager1 name1 v + # Add no2 address2 manager1 name2 x + activate_node_operators_calldata = prepare_activate_node_operator_calldata(no1, manager1) + add_node_operator_calldata = prepare_add_node_operator_calldata(1, name2, address2, manager1) + + easytrack_pair_executor_with_collision( + reverts("MANAGER_ALREADY_HAS_ROLE"), + [ + (commitee_multisig, activate_node_operators_factory, activate_node_operators_calldata), + (commitee_multisig, add_node_operators_factory, add_node_operator_calldata), + ], + ) + + # 3) ChangeNodeOperatorManagers - AddNodeOperators -> MANAGER_ALREADY_HAS_ROLE + # change no1 address1 manager1->2 name1 v + # add no2 address2 manager2 name2 x + change_node_operator_manager_calldata = prepare_change_node_operator_manager_calldata(no1, manager1, manager2) + add_node_operator_calldata = prepare_add_node_operator_calldata(1, name2, address2, manager2) + + easytrack_pair_executor_with_collision( + reverts("MANAGER_ALREADY_HAS_ROLE"), + [ + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata), + (commitee_multisig, add_node_operators_factory, add_node_operator_calldata), + ], + ) + + # 4) DeactivateNodeOperators - DeactivateNodeOperators + # deactivate no1 address1 manager2 name1 v + # deactivate no1 address1 manager2 name1 x + deactivate_node_operator_calldata = prepare_deactivate_node_operator_calldata(no1, manager2) + easytrack_pair_executor_with_collision( + reverts("WRONG_OPERATOR_ACTIVE_STATE"), + [ + (commitee_multisig, deactivate_node_operators_factory, deactivate_node_operator_calldata), + (commitee_multisig, deactivate_node_operators_factory, deactivate_node_operator_calldata), + ], + ) + + # 5) DeactivateNodeOperators - DeactivateNodeOperators -> WRONG_OPERATOR_ACTIVE_STATE + # add no2 address2 manager2 name2 v + # activate no1 address1 manager2 name1 x + add_node_operator_calldata = prepare_add_node_operator_calldata(1, name2, address2, manager2) + activate_node_operators_calldata = prepare_activate_node_operator_calldata(no1, manager2) + + easytrack_pair_executor_with_collision( + reverts("MANAGER_ALREADY_HAS_ROLE"), + [ + (commitee_multisig, add_node_operators_factory, add_node_operator_calldata), + (commitee_multisig, activate_node_operators_factory, activate_node_operators_calldata), + ], + ) + + # 6) ActivateNodeOperators - ActivateNodeOperators -> WRONG_OPERATOR_ACTIVE_STATE + # activate no1 address1 manager1 name1 + # activate no1 address1 manager1 name1 + activate_node_operators_calldata = prepare_activate_node_operator_calldata(no1, manager1) + + easytrack_pair_executor_with_collision( + reverts("WRONG_OPERATOR_ACTIVE_STATE"), + [ + (commitee_multisig, activate_node_operators_factory, activate_node_operators_calldata), + (commitee_multisig, activate_node_operators_factory, activate_node_operators_calldata), + ], + ) + + # -) deactivate no2 + deactivate_node_operator_calldata = prepare_deactivate_node_operator_calldata(no2, manager2) + + easytrack_executor( + commitee_multisig, + deactivate_node_operators_factory, + deactivate_node_operator_calldata, + ) + + # 7) ChangeNodeOperatorManagers - ActivateNodeOperators -> MANAGER_ALREADY_HAS_ROLE + # change no1 address1 manager1->2 name1 v + # activate no2 address2 manager2 name2 x + change_node_operator_manager_calldata = prepare_change_node_operator_manager_calldata(no1, manager1, manager2) + activate_node_operators_calldata = prepare_activate_node_operator_calldata(no2, manager2) + + easytrack_pair_executor_with_collision( + reverts("MANAGER_ALREADY_HAS_ROLE"), + [ + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata), + (commitee_multisig, activate_node_operators_factory, activate_node_operators_calldata), + ], + ) + + # 8) SetNodeOperatorNames - SetNodeOperatorNames -> SAME_NAME + # set no1 address1 manager2 name1->3 v + # set no1 address1 manager2 name1->3 x + set_node_operator_name_calldata = prepare_set_node_operator_name_calldata(no1, name3) + + easytrack_pair_executor_with_collision( + reverts("SAME_NAME"), + [ + (commitee_multisig, set_node_operator_name_factory, set_node_operator_name_calldata), + (commitee_multisig, set_node_operator_name_factory, set_node_operator_name_calldata), + ], + ) + + # 9) SetNodeOperatorRewardAddresses- SetNodeOperatorRewardAddresses -> SAME_REWARD_ADDRESS + # set no1 address1->3 manager2 name3 v + # set no1 address1->3 manager2 name3 x + set_node_operator_reward_address_calldata = prepare_set_node_operator_reward_address_calldata(no1, address3) + + easytrack_pair_executor_with_collision( + reverts("SAME_REWARD_ADDRESS"), + [ + (commitee_multisig, set_node_operator_reward_address_factory, set_node_operator_reward_address_calldata), + (commitee_multisig, set_node_operator_reward_address_factory, set_node_operator_reward_address_calldata), + ], + ) + + # 10) AddNodeOperators - ChangeNodeOperatorManagers -> MANAGER_ALREADY_HAS_ROLE + # add no3 address1 manager3 name1 v + # change no1 address3 manager2->3 name3 x + add_node_operator_calldata = prepare_add_node_operator_calldata(2, name1, address1, manager3) + change_node_operator_manager_calldata = prepare_change_node_operator_manager_calldata(no1, manager2, manager3) + + easytrack_pair_executor_with_collision( + reverts("MANAGER_ALREADY_HAS_ROLE"), + [ + (commitee_multisig, add_node_operators_factory, add_node_operator_calldata), + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata), + ], + ) + + # 11) ActivateNodeOperators - ChangeNodeOperatorManagers -> MANAGER_ALREADY_HAS_ROLE + # activate no2 address2 manager1 name2 v + # change no1 address3 manager2->1 name3 x + activate_node_operators_calldata = prepare_activate_node_operator_calldata(no2, manager1) + change_node_operator_manager_calldata = prepare_change_node_operator_manager_calldata(no1, manager2, manager1) + + easytrack_pair_executor_with_collision( + reverts("MANAGER_ALREADY_HAS_ROLE"), + [ + (commitee_multisig, activate_node_operators_factory, activate_node_operators_calldata), + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata), + ], + ) + + # 12) ChangeNodeOperatorManagers - ChangeNodeOperatorManagers -> OLD_MANAGER_HAS_NO_ROLE + # change no1 address3 manager2->4 name3 v + # change no1 address3 manager2->4 name3 x + change_node_operator_manager_calldata = prepare_change_node_operator_manager_calldata(no1, manager2, manager4) + easytrack_pair_executor_with_collision( + reverts("OLD_MANAGER_HAS_NO_ROLE"), + [ + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata), + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata), + ], + ) + + # 13) ChangeNodeOperatorManagers - ChangeNodeOperatorManagers -> MANAGER_ALREADY_HAS_ROLE + # change no1 address3 manager4->2 name3 v + # change no2 address2 manager1->2 name2 x + change_node_operator_manager_calldata1 = prepare_change_node_operator_manager_calldata(no1, manager4, manager2) + change_node_operator_manager_calldata2 = prepare_change_node_operator_manager_calldata(no2, manager1, manager2) + easytrack_pair_executor_with_collision( + reverts("MANAGER_ALREADY_HAS_ROLE"), + [ + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata1), + (commitee_multisig, change_node_operator_manager_factory, change_node_operator_manager_calldata2), + ], + ) + + # addSigningKeysOperatorBH no1 address3 manager4 name3 + simple_dvt.addSigningKeysOperatorBH( + no1, + len(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["pubkeys"]), + "0x" + "".join(signing_keys["signatures"]), + {"from": manager2}, + ) + + # 14) DeactivateNodeOperators - IncreaseVettedValidatorsLimit -> STAKING_LIMIT_TOO_LOW + # set vetted no1 address3 manager2 name3 vl->1 v + # increase vetted no1 address3 manager2 name3 vt->1 x + set_vetted_validators_limit_calldata = prepare_set_vetted_validators_limit_calldata(no1, 1) + increase_vetted_validators_limit_calldata = prepare_increase_vetted_validators_limit_calldata(no1, 1) + + easytrack_pair_executor_with_collision( + reverts("STAKING_LIMIT_TOO_LOW"), + [ + (commitee_multisig, set_vetted_validators_limit_factory, set_vetted_validators_limit_calldata), + (manager2, increase_vetted_validators_limit_factory, increase_vetted_validators_limit_calldata), + ], + ) + + # 15) IncreaseVettedValidatorsLimit - IncreaseVettedValidatorsLimit -> STAKING_LIMIT_TOO_LOW + # increase vetted no1 address3 manager2 name3 vl->2 v + # increase vetted no1 address3 manager2 name3 vt->2 x + increase_vetted_validators_limit_calldata1 = prepare_increase_vetted_validators_limit_calldata(no1, 2) + increase_vetted_validators_limit_calldata2 = prepare_increase_vetted_validators_limit_calldata(no1, 2) + + easytrack_pair_executor_with_collision( + reverts("STAKING_LIMIT_TOO_LOW"), + [ + (manager2, increase_vetted_validators_limit_factory, increase_vetted_validators_limit_calldata1), + (manager2, increase_vetted_validators_limit_factory, increase_vetted_validators_limit_calldata2), + ], + ) + + # 16) DeactivateNodeOperators - IncreaseVettedValidatorsLimit -> CALLER_IS_NOT_NODE_OPERATOR_OR_MANAGER + # deactivate no1 address3 manager2 name3 v + # increase vetted no1 address3 manager2 name3 vt->3 x + deactivate_node_operator_calldata = prepare_deactivate_node_operator_calldata(no1, manager2) + increase_vetted_validators_limit_calldata = prepare_increase_vetted_validators_limit_calldata(no1, 3) + + easytrack_pair_executor_with_collision( + reverts("CALLER_IS_NOT_NODE_OPERATOR_OR_MANAGER"), + [ + (commitee_multisig, deactivate_node_operators_factory, deactivate_node_operator_calldata), + (manager2, increase_vetted_validators_limit_factory, increase_vetted_validators_limit_calldata), + ], + ) diff --git a/tests/scenario/test_dvt_signing_keys_role.py b/tests/scenario/test_dvt_signing_keys_role.py new file mode 100644 index 00000000..f17fb847 --- /dev/null +++ b/tests/scenario/test_dvt_signing_keys_role.py @@ -0,0 +1,228 @@ +import pytest +from eth_abi import encode +from brownie import web3, interface +from utils.permission_parameters import Op, Param, encode_permission_params +from utils.evm_script import encode_call_script + +clusters = [ + { + "address": "0x000000000000000000000000000000000000{:04}".format(i), + "manager": "0x000000000000000000000000000000000000{:04}".format(i), + "name": "Cluster " + str(i), + } + for i in range(1, 8) +] + + +@pytest.fixture(scope="module") +def simple_dvt( + node_operators_registry, + kernel, + voting, + locator, + staking_router, + agent, + acl, +): + nor_proxy = interface.AragonAppProxy(node_operators_registry) + module_name = "simple-dvt-registry" + name = web3.keccak(text=module_name).hex() + simple_DVT_tx = kernel.newAppInstance(name, nor_proxy.implementation(), {"from": voting}) + + simple_dvt_contract = interface.NodeOperatorsRegistry(simple_DVT_tx.new_contracts[0]) + + simple_dvt_contract.initialize(locator, "0x01", 0, {"from": voting}) + + staking_router.grantRole(web3.keccak(text="STAKING_MODULE_MANAGE_ROLE").hex(), agent, {"from": agent}) + + staking_router.addStakingModule("Simple DVT", simple_dvt_contract, 10_000, 500, 500, {"from": agent}) + + acl.createPermission( + agent, + simple_dvt_contract, + web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE").hex(), + agent, + {"from": voting}, + ) + + return simple_dvt_contract + + +@pytest.fixture(scope="module") +def grant_roles(acl, et_contracts, agent, voting, simple_dvt): + # Grant roles + acl.grantPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.MANAGE_NODE_OPERATOR_ROLE(), + {"from": agent}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.SET_NODE_OPERATOR_LIMIT_ROLE(), + agent, + {"from": voting}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.MANAGE_SIGNING_KEYS(), + et_contracts.evm_script_executor, + {"from": voting}, + ) + acl.createPermission( + et_contracts.evm_script_executor, + simple_dvt, + simple_dvt.STAKING_ROUTER_ROLE(), + agent, + {"from": voting}, + ) + + +def test_simple_make_action( + simple_dvt, + commitee_multisig, + et_contracts, + acl, + agent, + easytrack_executor, + add_node_operators_factory, + grant_roles, + lido_contracts, + stranger, + change_node_operator_manager_factory, +): + # Add clusters + add_node_operators_calldata = ( + "0x" + + encode( + ["uint256", "(string,address,address)[]"], + [ + 0, + [(cluster["name"], cluster["address"], cluster["manager"]) for cluster in clusters], + ], + ).hex() + ) + + easytrack_executor(commitee_multisig, add_node_operators_factory, add_node_operators_calldata) + + for cluster_index in range(len(clusters)): + cluster = simple_dvt.getNodeOperator(cluster_index, True) + assert cluster["active"] == True + assert cluster["name"] == clusters[cluster_index]["name"] + assert cluster["rewardAddress"] == clusters[cluster_index]["address"] + assert cluster["totalVettedValidators"] == 0 + assert cluster["totalExitedValidators"] == 0 + assert cluster["totalAddedValidators"] == 0 + assert cluster["totalDepositedValidators"] == 0 + assert ( + simple_dvt.canPerform( + clusters[cluster_index]["manager"], + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, cluster_index)]), + ) + == True + ) + + # Renounce MANAGE_SIGNING_KEYS role manager + + vote_script_calldata = encode_call_script( + [ + ( + et_contracts.evm_script_executor.address, + et_contracts.evm_script_executor.setEasyTrack.encode_input(agent), + ), + encode_agent_forward( + agent, + [ + encode_execute_evm_script( + et_contracts.evm_script_executor, + ( + acl.address, + acl.setPermissionManager.encode_input( + agent, + simple_dvt, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + ), + ), + ), + ( + acl.address, + acl.grantPermission.encode_input( + agent.address, + simple_dvt, + simple_dvt.MANAGE_SIGNING_KEYS(), + ), + ), + ( + acl.address, + acl.setPermissionManager.encode_input( + et_contracts.evm_script_executor, + simple_dvt, + web3.keccak(text="MANAGE_SIGNING_KEYS").hex(), + ), + ), + ], + ), + ( + et_contracts.evm_script_executor.address, + et_contracts.evm_script_executor.setEasyTrack.encode_input(et_contracts.easy_track), + ), + ] + ) + + voting_id, _ = lido_contracts.create_voting( + evm_script=vote_script_calldata, + description="Update MANAGE_SIGNING_KEYS roles manager.", + tx_params={"from": lido_contracts.aragon.agent}, + ) + + lido_contracts.execute_voting(voting_id) + + assert acl.getPermissionManager(simple_dvt, simple_dvt.MANAGE_SIGNING_KEYS()) == et_contracts.evm_script_executor + + assert acl.hasPermission(agent, simple_dvt, simple_dvt.MANAGE_SIGNING_KEYS()) == True + + assert et_contracts.evm_script_executor.easyTrack() == et_contracts.easy_track + + # Transfer cluster manager + + # add signing keys to node operator + no_5_id = 5 + no_5 = simple_dvt.getNodeOperator(no_5_id, False) + change_node_operator_manager_calldata = ( + "0x" + + encode( + ["(uint256,address,address)[]"], + [[(no_5_id, clusters[no_5_id]["manager"], stranger.address)]], + ).hex() + ) + + easytrack_executor( + commitee_multisig, + change_node_operator_manager_factory, + change_node_operator_manager_calldata, + ) + + assert not simple_dvt.canPerform( + clusters[no_5_id]["manager"], + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, no_5_id)]), + ) + assert simple_dvt.canPerform( + stranger, + simple_dvt.MANAGE_SIGNING_KEYS(), + encode_permission_params([Param(0, Op.EQ, no_5_id)]), + ) + + +def encode_agent_forward(agent, scripts): + return (agent.address, agent.forward.encode_input(encode_call_script(scripts))) + + +def encode_execute_evm_script(evm_script_executor, script): + return ( + evm_script_executor.address, + evm_script_executor.executeEVMScript.encode_input(encode_call_script([script])), + ) diff --git a/tests/scripts/test_deploy_script.py b/tests/scripts/test_deploy_script.py index f65551c1..851db21a 100644 --- a/tests/scripts/test_deploy_script.py +++ b/tests/scripts/test_deploy_script.py @@ -1,5 +1,6 @@ +import brownie from scripts.deploy import deploy_easy_tracks -from utils import lido, constants, deployment +from utils import lido, constants def test_deploy_script(accounts): @@ -8,7 +9,7 @@ def test_deploy_script(accounts): lego_committee_multisig = accounts[2] reward_programs_multisig = accounts[3] pause_address = accounts[4] - lido_contracts = lido.contracts(network="mainnet") + lido_contracts = lido.contracts(network=brownie.network.show_active()) ( easy_track, evm_script_executor, @@ -34,36 +35,25 @@ def test_deploy_script(accounts): assert easy_track.hasRole(easy_track.PAUSE_ROLE(), lido_contracts.aragon.voting) assert easy_track.hasRole(easy_track.CANCEL_ROLE(), lido_contracts.aragon.voting) assert easy_track.hasRole(easy_track.UNPAUSE_ROLE(), lido_contracts.aragon.voting) - assert easy_track.hasRole( - easy_track.DEFAULT_ADMIN_ROLE(), lido_contracts.aragon.voting - ) + assert easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), lido_contracts.aragon.voting) assert not easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer) assert evm_script_executor.callsScript() == lido_contracts.aragon.calls_script assert evm_script_executor.easyTrack() == easy_track assert evm_script_executor.owner() == lido_contracts.aragon.voting - assert ( - increase_node_operators_staking_limit.nodeOperatorsRegistry() - == lido_contracts.node_operators_registry - ) + assert increase_node_operators_staking_limit.nodeOperatorsRegistry() == lido_contracts.node_operators_registry assert top_up_lego_program.finance() == lido_contracts.aragon.finance assert top_up_lego_program.legoProgram() == lego_program_vault assert top_up_lego_program.trustedCaller() == lego_committee_multisig - assert reward_programs_registry.hasRole( - reward_programs_registry.DEFAULT_ADMIN_ROLE(), lido_contracts.aragon.voting - ) - assert reward_programs_registry.hasRole( - reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), evm_script_executor - ) + assert reward_programs_registry.hasRole(reward_programs_registry.DEFAULT_ADMIN_ROLE(), lido_contracts.aragon.voting) + assert reward_programs_registry.hasRole(reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), evm_script_executor) assert reward_programs_registry.hasRole( reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), lido_contracts.aragon.voting ) - assert reward_programs_registry.hasRole( - reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), evm_script_executor - ) + assert reward_programs_registry.hasRole(reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), evm_script_executor) assert reward_programs_registry.hasRole( reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), lido_contracts.aragon.voting, @@ -83,39 +73,22 @@ def test_deploy_script(accounts): # validate evm script factories permissions set_node_operator_staking_limit_permission = ( lido_contracts.node_operators_registry.address - + lido_contracts.node_operators_registry.setNodeOperatorStakingLimit.signature[ - 2: - ] + + lido_contracts.node_operators_registry.setNodeOperatorStakingLimit.signature[2:] ) new_immediate_payment_permission = ( - lido_contracts.aragon.finance.address - + lido_contracts.aragon.finance.newImmediatePayment.signature[2:] + lido_contracts.aragon.finance.address + lido_contracts.aragon.finance.newImmediatePayment.signature[2:] ) add_reward_program_permission = ( - reward_programs_registry.address - + reward_programs_registry.addRewardProgram.signature[2:] + reward_programs_registry.address + reward_programs_registry.addRewardProgram.signature[2:] ) remove_reward_program_permission = ( - reward_programs_registry.address - + reward_programs_registry.removeRewardProgram.signature[2:] + reward_programs_registry.address + reward_programs_registry.removeRewardProgram.signature[2:] ) assert ( easy_track.evmScriptFactoryPermissions(increase_node_operators_staking_limit) == set_node_operator_staking_limit_permission ) - assert ( - easy_track.evmScriptFactoryPermissions(top_up_lego_program) - == new_immediate_payment_permission - ) - assert ( - easy_track.evmScriptFactoryPermissions(add_reward_program) - == add_reward_program_permission - ) - assert ( - easy_track.evmScriptFactoryPermissions(remove_reward_program) - == remove_reward_program_permission - ) - assert ( - easy_track.evmScriptFactoryPermissions(top_up_reward_programs) - == new_immediate_payment_permission - ) + assert easy_track.evmScriptFactoryPermissions(top_up_lego_program) == new_immediate_payment_permission + assert easy_track.evmScriptFactoryPermissions(add_reward_program) == add_reward_program_permission + assert easy_track.evmScriptFactoryPermissions(remove_reward_program) == remove_reward_program_permission + assert easy_track.evmScriptFactoryPermissions(top_up_reward_programs) == new_immediate_payment_permission diff --git a/tests/scripts/test_grant_executor_permissions.py b/tests/scripts/test_grant_executor_permissions.py index 32707489..34e2e434 100644 --- a/tests/scripts/test_grant_executor_permissions.py +++ b/tests/scripts/test_grant_executor_permissions.py @@ -1,10 +1,11 @@ +import brownie from scripts.grant_executor_permissions import grant_executor_permissions from scripts.deploy import deploy_easy_tracks from utils import lido def test_grant_executor_permissions(accounts): - lido_contracts = lido.contracts(network="mainnet") + lido_contracts = lido.contracts(network=brownie.network.show_active()) deployer = accounts[0] lego_program_vault = accounts[1] lego_committee_multisig = accounts[2] @@ -19,30 +20,24 @@ def test_grant_executor_permissions(accounts): tx_params={"from": deployer}, )[1] - lido_permissions = lido.permissions(contracts=lido_contracts) + lido_permissions = lido_contracts.permissions required_permissions = [ lido_permissions.finance.CREATE_PAYMENTS_ROLE, lido_permissions.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE, ] for permission in required_permissions: - assert not lido_contracts.aragon.acl.hasPermission( - evm_script_executor, permission.app, permission.role - ) + assert not lido_contracts.aragon.acl.hasPermission(evm_script_executor, permission.app, permission.role) - lido_contracts.ldo.transfer( - deployer, 10 ** 18, {"from": lido_contracts.aragon.agent} - ) + lido_contracts.ldo.transfer(deployer, 10**18, {"from": lido_contracts.aragon.agent}) voting_id = grant_executor_permissions( - acl=lido_contracts.aragon.acl, + lido_contracts=lido_contracts, evm_script_executor=evm_script_executor.address, permissions_to_grant=required_permissions, tx_params={"from": deployer}, ) - lido.execute_voting(voting_id) + lido_contracts.execute_voting(voting_id) for permission in required_permissions: - assert lido_contracts.aragon.acl.hasPermission( - evm_script_executor, permission.app, permission.role - ) + assert lido_contracts.aragon.acl.hasPermission(evm_script_executor, permission.app, permission.role) diff --git a/tests/scripts/test_revoke_all_permissions.py b/tests/scripts/test_revoke_all_permissions.py index 2168ee45..2fa5580d 100644 --- a/tests/scripts/test_revoke_all_permissions.py +++ b/tests/scripts/test_revoke_all_permissions.py @@ -1,3 +1,4 @@ +from brownie import network from scripts.revoke_all_permissions import revoke_permissions from scripts.grant_executor_permissions import grant_executor_permissions from scripts.deploy import deploy_easy_tracks @@ -5,7 +6,7 @@ def test_revoke_permissions(accounts): - lido_contracts = lido.contracts(network="mainnet") + lido_contracts = lido.contracts(network=network.show_active()) deployer = accounts[0] lego_program_vault = accounts[1] lego_committee_multisig = accounts[2] @@ -20,28 +21,24 @@ def test_revoke_permissions(accounts): tx_params={"from": deployer}, )[1] - lido_permissions = lido.permissions(contracts=lido_contracts) + lido_permissions = lido_contracts.permissions permissions = [ lido_permissions.finance.CREATE_PAYMENTS_ROLE, lido_permissions.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE, ] - lido_contracts.ldo.transfer( - deployer, 10 ** 18, {"from": lido_contracts.aragon.agent} - ) + lido_contracts.ldo.transfer(deployer, 10**18, {"from": lido_contracts.aragon.agent}) voting_id = grant_executor_permissions( - acl=lido_contracts.aragon.acl, + lido_contracts=lido_contracts, evm_script_executor=evm_script_executor.address, permissions_to_grant=permissions, tx_params={"from": deployer}, ) - lido.execute_voting(voting_id) + lido_contracts.execute_voting(voting_id) for permission in permissions: - assert lido_contracts.aragon.acl.hasPermission( - evm_script_executor, permission.app, permission.role - ) + assert lido_contracts.aragon.acl.hasPermission(evm_script_executor, permission.app, permission.role) voting_id = revoke_permissions( lido_contracts=lido_contracts, @@ -50,9 +47,7 @@ def test_revoke_permissions(accounts): tx_params={"from": deployer}, ) - lido.execute_voting(voting_id) + lido_contracts.execute_voting(voting_id) for permission in lido_permissions.all(): - assert not lido_contracts.aragon.acl.hasPermission( - evm_script_executor, permission.app, permission.role - ) + assert not lido_contracts.aragon.acl.hasPermission(evm_script_executor, permission.app, permission.role) diff --git a/tests/test_allowed_recipients_builder.py b/tests/test_allowed_recipients_builder.py new file mode 100644 index 00000000..e5101f0f --- /dev/null +++ b/tests/test_allowed_recipients_builder.py @@ -0,0 +1,356 @@ +import pytest +from brownie import Contract, reverts + +ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE = "0xec20c52871c824e5437859e75ac830e83aaaaeb7b0ffd850de830ddd3e385276" +REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE = "0x491d7752c25cfca0f73715cde1130022a9b815373f91a996bbb1ba8943efc99b" +SET_PARAMETERS_ROLE = "0x260b83d52a26066d8e9db550fa70395df5f3f064b50ff9d8a94267d9f1fe1967" +UPDATE_SPENT_AMOUNT_ROLE = "0xc5260260446719a726d11a6faece21d19daa48b4cbcca118345832d4cb71df99" +DEFAULT_ADMIN_ROLE = "0x00" + + +@pytest.fixture(scope="module") +def allowed_recipients_factory(owner, AllowedRecipientsFactory): + return owner.deploy( + AllowedRecipientsFactory, + ) + + +@pytest.fixture(scope="module") +def allowed_recipients_builder( + owner, + AllowedRecipientsBuilder, + allowed_recipients_factory, + agent, + finance, + easy_track, + bokkyPooBahsDateTimeContract, +): + return owner.deploy( + AllowedRecipientsBuilder, + allowed_recipients_factory, + agent, + easy_track, + finance, + bokkyPooBahsDateTimeContract, + ) + + +def test_builder_constructor_params( + allowed_recipients_factory, + easy_track, + evm_script_executor, + agent, + finance, + bokkyPooBahsDateTimeContract, + allowed_recipients_builder, +): + assert allowed_recipients_builder.factory() == allowed_recipients_factory + assert allowed_recipients_builder.admin() == agent + assert allowed_recipients_builder.finance() == finance + assert allowed_recipients_builder.easyTrack() == easy_track + assert allowed_recipients_builder.bokkyPooBahsDateTimeContract() == bokkyPooBahsDateTimeContract + assert allowed_recipients_builder.evmScriptExecutor() == evm_script_executor + + +def test_deploy_top_up_allowed_recipients( + allowed_recipients_builder, + accounts, + stranger, + ldo, + finance, + easy_track, + TopUpAllowedRecipients, +): + trusted_caller = accounts[3] + registry = accounts[4] + + tx = allowed_recipients_builder.deployTopUpAllowedRecipients(trusted_caller, registry, ldo, {"from": stranger}) + + top_up_address = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + + assert tx.events["TopUpAllowedRecipientsDeployed"]["creator"] == allowed_recipients_builder + assert tx.events["TopUpAllowedRecipientsDeployed"]["trustedCaller"] == trusted_caller + assert tx.events["TopUpAllowedRecipientsDeployed"]["allowedRecipientsRegistry"] == registry + assert tx.events["TopUpAllowedRecipientsDeployed"]["finance"] == finance + assert tx.events["TopUpAllowedRecipientsDeployed"]["token"] == ldo + assert tx.events["TopUpAllowedRecipientsDeployed"]["easyTrack"] == easy_track + + topUpAllowedRecipients = Contract.from_abi("TopUpAllowedRecipients", top_up_address, TopUpAllowedRecipients.abi) + assert topUpAllowedRecipients.token() == ldo + assert topUpAllowedRecipients.allowedRecipientsRegistry() == registry + assert topUpAllowedRecipients.trustedCaller() == trusted_caller + assert topUpAllowedRecipients.finance() == finance + assert topUpAllowedRecipients.token() == ldo + assert topUpAllowedRecipients.easyTrack() == easy_track + + +def test_deploy_add_allowed_recipient(allowed_recipients_builder, accounts, stranger, AddAllowedRecipient): + trusted_caller = accounts[3] + registry = accounts[4] + + tx = allowed_recipients_builder.deployAddAllowedRecipient(trusted_caller, registry, {"from": stranger}) + + add_recipient_address = tx.events["AddAllowedRecipientDeployed"]["addAllowedRecipient"] + + assert tx.events["AddAllowedRecipientDeployed"]["creator"] == allowed_recipients_builder + assert tx.events["AddAllowedRecipientDeployed"]["trustedCaller"] == trusted_caller + assert tx.events["AddAllowedRecipientDeployed"]["allowedRecipientsRegistry"] == registry + + addAllowedRecipient = Contract.from_abi("AddAllowedRecipient", add_recipient_address, AddAllowedRecipient.abi) + + assert addAllowedRecipient.allowedRecipientsRegistry() == registry + assert addAllowedRecipient.trustedCaller() == trusted_caller + + +def test_deploy_remove_allowed_recipient(allowed_recipients_builder, accounts, stranger, RemoveAllowedRecipient): + trusted_caller = accounts[3] + registry = accounts[4] + + tx = allowed_recipients_builder.deployRemoveAllowedRecipient(trusted_caller, registry, {"from": stranger}) + + remove_allowed_recipient_address = tx.events["RemoveAllowedRecipientDeployed"]["removeAllowedRecipient"] + + assert tx.events["RemoveAllowedRecipientDeployed"]["creator"] == allowed_recipients_builder + assert tx.events["RemoveAllowedRecipientDeployed"]["trustedCaller"] == trusted_caller + assert tx.events["RemoveAllowedRecipientDeployed"]["allowedRecipientsRegistry"] == registry + + removeAllowedRecipient = Contract.from_abi( + "RemoveAllowedRecipient", + remove_allowed_recipient_address, + RemoveAllowedRecipient.abi, + ) + + assert removeAllowedRecipient.allowedRecipientsRegistry() == registry + assert removeAllowedRecipient.trustedCaller() == trusted_caller + + +def test_deploy_allowed_recipients_registry( + allowed_recipients_builder, + accounts, + stranger, + agent, + evm_script_executor, + AllowedRecipientsRegistry, +): + limit = 1e18 + period = 1 + recipients = [accounts[3], accounts[4]] + titles = ["account 3", "account 4"] + spentAmount = 1e10 + + tx = allowed_recipients_builder.deployAllowedRecipientsRegistry( + limit, period, recipients, titles, spentAmount, True, {"from": stranger} + ) + + registry_address = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + + registry = Contract.from_abi("AllowedRecipientsRegistry", registry_address, AllowedRecipientsRegistry.abi) + + assert len(registry.getAllowedRecipients()) == len(recipients) + for recipient in recipients: + assert registry.isRecipientAllowed(recipient) + + registry_limit, registry_period_duration = registry.getLimitParameters() + assert registry_limit == limit + assert registry_period_duration == period + + assert registry.spendableBalance() == limit - spentAmount + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, agent) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, agent) + assert registry.hasRole(SET_PARAMETERS_ROLE, agent) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, agent) + assert registry.hasRole(DEFAULT_ADMIN_ROLE, agent) + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, evm_script_executor) + assert not registry.hasRole(SET_PARAMETERS_ROLE, evm_script_executor) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, evm_script_executor) + + assert not registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(SET_PARAMETERS_ROLE, registry_address) + assert not registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, registry_address) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, registry_address) + + +def test_deploy_recipients_registry_reverts_recipients_length(allowed_recipients_builder, accounts, stranger): + limit = 1e18 + period = 1 + recipients = [accounts[3], accounts[4]] + titles = ["account 3"] + spentAmount = 1e10 + + with reverts(): + allowed_recipients_builder.deployAllowedRecipientsRegistry( + limit, period, recipients, titles, spentAmount, False, {"from": stranger} + ) + + +def test_deploy_recipients_registry_reverts_spentAmount_gt_limit(allowed_recipients_builder, accounts, stranger): + limit = 1e5 + period = 1 + recipients = [accounts[3], accounts[4]] + titles = ["account 3", "account 4"] + spentAmount = 1e10 + + with reverts("_spentAmount must be lower or equal to limit"): + allowed_recipients_builder.deployAllowedRecipientsRegistry( + limit, period, recipients, titles, spentAmount, False, {"from": stranger} + ) + + +def test_deploy_full_setup( + allowed_recipients_builder, + stranger, + agent, + ldo, + evm_script_executor, + AllowedRecipientsRegistry, + AddAllowedRecipient, + RemoveAllowedRecipient, + TopUpAllowedRecipients, +): + + recipients = [ + "0xbbe8dDEf5BF31b71Ff5DbE89635f9dB4DeFC667E", + "0x07fC01f46dC1348d7Ce43787b5Bbd52d8711a92D", + "0xa5F1d7D49F581136Cf6e58B32cBE9a2039C48bA1", + "0xDDFFac49946D1F6CE4d9CaF3B9C7d340d4848A1C", + "0xc6e2459991BfE27cca6d86722F35da23A1E4Cb97", + ] + titles = [ + "Default Reward Program", + "Happy", + "Sergey'2 #add RewardProgram", + "Jumpgate Test", + "tester", + ] + trusted_caller = "0x3eaE0B337413407FB3C65324735D797ddc7E071D" + limit = 10_000 * 1e18 + period = 1 + spent_amount = 0 + + tx = allowed_recipients_builder.deployFullSetup( + trusted_caller, + ldo, + limit, + period, + recipients, + titles, + spent_amount, + {"from": stranger}, + ) + + registry_address = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + top_up_address = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + add_recipient_address = tx.events["AddAllowedRecipientDeployed"]["addAllowedRecipient"] + remove_allowed_recipient_address = tx.events["RemoveAllowedRecipientDeployed"]["removeAllowedRecipient"] + + registry = Contract.from_abi("AllowedRecipientsRegistry", registry_address, AllowedRecipientsRegistry.abi) + + top_up_allowed_recipients = Contract.from_abi("TopUpAllowedRecipients", top_up_address, TopUpAllowedRecipients.abi) + + add_allowed_recipient = Contract.from_abi("AddAllowedRecipient", add_recipient_address, AddAllowedRecipient.abi) + + remove_allowed_recipient = Contract.from_abi( + "RemoveAllowedRecipient", + remove_allowed_recipient_address, + RemoveAllowedRecipient.abi, + ) + + assert top_up_allowed_recipients.token() == ldo + assert top_up_allowed_recipients.allowedRecipientsRegistry() == registry + assert top_up_allowed_recipients.trustedCaller() == trusted_caller + assert add_allowed_recipient.allowedRecipientsRegistry() == registry + assert add_allowed_recipient.trustedCaller() == trusted_caller + assert remove_allowed_recipient.allowedRecipientsRegistry() == registry + assert remove_allowed_recipient.trustedCaller() == trusted_caller + + assert len(registry.getAllowedRecipients()) == len(recipients) + for recipient in recipients: + assert registry.isRecipientAllowed(recipient) + + registry_limit, registry_period_duration = registry.getLimitParameters() + assert registry_limit == limit + assert registry_period_duration == period + + assert registry.spendableBalance() == limit - spent_amount + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, agent) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, agent) + assert registry.hasRole(SET_PARAMETERS_ROLE, agent) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, agent) + assert registry.hasRole(DEFAULT_ADMIN_ROLE, agent) + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, evm_script_executor) + assert not registry.hasRole(SET_PARAMETERS_ROLE, evm_script_executor) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, evm_script_executor) + + assert not registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(SET_PARAMETERS_ROLE, registry_address) + assert not registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, registry_address) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, registry_address) + + +def test_deploy_deploy_single_recipient_top_up_only_setup( + allowed_recipients_builder, + accounts, + agent, + ldo, + stranger, + evm_script_executor, + AllowedRecipientsRegistry, + TopUpAllowedRecipients, +): + + recipient = accounts[2] + title = "recipient" + limit = 1e18 + period = 1 + spent_amount = 1e10 + + tx = allowed_recipients_builder.deploySingleRecipientTopUpOnlySetup( + recipient, title, ldo, limit, period, spent_amount, {"from": stranger} + ) + + registry_address = tx.events["AllowedRecipientsRegistryDeployed"]["allowedRecipientsRegistry"] + top_up_address = tx.events["TopUpAllowedRecipientsDeployed"]["topUpAllowedRecipients"] + + registry = Contract.from_abi("AllowedRecipientsRegistry", registry_address, AllowedRecipientsRegistry.abi) + + top_up_allowed_recipients = Contract.from_abi("TopUpAllowedRecipients", top_up_address, TopUpAllowedRecipients.abi) + + assert top_up_allowed_recipients.allowedRecipientsRegistry() == registry + assert top_up_allowed_recipients.token() == ldo + + assert len(registry.getAllowedRecipients()) == 1 + assert registry.isRecipientAllowed(recipient) + + registry_limit, registry_period_duration = registry.getLimitParameters() + assert registry_limit == limit + assert registry_period_duration == period + + assert registry.spendableBalance() == limit - spent_amount + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, agent) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, agent) + assert registry.hasRole(SET_PARAMETERS_ROLE, agent) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, agent) + assert registry.hasRole(DEFAULT_ADMIN_ROLE, agent) + + assert not registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, evm_script_executor) + assert not registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, evm_script_executor) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, evm_script_executor) + assert not registry.hasRole(SET_PARAMETERS_ROLE, evm_script_executor) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, evm_script_executor) + + assert not registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, registry_address) + assert not registry.hasRole(SET_PARAMETERS_ROLE, registry_address) + assert not registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, registry_address) + assert not registry.hasRole(DEFAULT_ADMIN_ROLE, registry_address) diff --git a/tests/test_allowed_recipients_registry.py b/tests/test_allowed_recipients_registry.py new file mode 100644 index 00000000..82244621 --- /dev/null +++ b/tests/test_allowed_recipients_registry.py @@ -0,0 +1,1092 @@ +import pytest +from datetime import datetime + +from brownie.network import chain +from brownie import accounts, reverts, ZERO_ADDRESS + + +from utils.test_helpers import ( + assert_single_event, + assert_event_exists, + access_revert_message, + get_month_start_timestamp, + get_date_in_next_period, + calc_period_first_month, + calc_period_range, + advance_chain_time_to_beginning_of_the_next_period, + SET_PARAMETERS_ROLE, + UPDATE_SPENT_AMOUNT_ROLE, + ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, + REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, +) + + +from utils.test_helpers import get_timestamp_from_date + + +MAX_SECONDS_IN_MONTH = 31 * 24 * 60 * 60 +RECIPIENT_TITLE = "New Allowed Recipient" + + +# ------------ +# constructor +# ------------ + + +def test_registry_initial_state(AllowedRecipientsRegistry, accounts, owner, bokkyPooBahsDateTimeContract): + add_recipient_role_holder = accounts[6] + remove_recipient_role_holder = accounts[7] + set_parameters_role_holder = accounts[8] + update_spent_role_holder = accounts[9] + + registry = owner.deploy( + AllowedRecipientsRegistry, + owner, + [add_recipient_role_holder], + [remove_recipient_role_holder], + [set_parameters_role_holder], + [update_spent_role_holder], + bokkyPooBahsDateTimeContract, + ) + + assert registry.hasRole(ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE, add_recipient_role_holder) + assert registry.hasRole(REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE, remove_recipient_role_holder) + assert registry.hasRole(SET_PARAMETERS_ROLE, set_parameters_role_holder) + assert registry.hasRole(UPDATE_SPENT_AMOUNT_ROLE, update_spent_role_holder) + assert registry.hasRole(registry.DEFAULT_ADMIN_ROLE(), owner) + + assert registry.bokkyPooBahsDateTimeContract() == bokkyPooBahsDateTimeContract + + for role_holder in [ + add_recipient_role_holder, + remove_recipient_role_holder, + set_parameters_role_holder, + update_spent_role_holder, + ]: + assert not registry.hasRole(registry.DEFAULT_ADMIN_ROLE(), role_holder) + + assert registry.spendableBalance() == 0 + assert registry.getLimitParameters() == (0, 0) + # brownie error + # with reverts(): + # registry.getPeriodState() + + assert len(registry.getAllowedRecipients()) == 0 + + +def test_registry_zero_admin_allowed(AllowedRecipientsRegistry, accounts, owner, bokkyPooBahsDateTimeContract): + """Checking no revert""" + owner.deploy( + AllowedRecipientsRegistry, + ZERO_ADDRESS, + [owner], + [owner], + [owner], + [owner], + bokkyPooBahsDateTimeContract, + ) + + +def test_registry_none_role_holders_allowed(AllowedRecipientsRegistry, accounts, owner, bokkyPooBahsDateTimeContract): + """Checking no revert""" + owner.deploy( + AllowedRecipientsRegistry, + owner, + [], + [], + [], + [], + bokkyPooBahsDateTimeContract, + ) + + +def test_registry_zero_booky_poo_bahs_data_time_address_allowed( + AllowedRecipientsRegistry, accounts, owner, bokkyPooBahsDateTimeContract +): + """Checking no revert""" + owner.deploy( + AllowedRecipientsRegistry, + owner, + [owner], + [owner], + [owner], + [owner], + ZERO_ADDRESS, + ) + + +# ------------ +# access control +# ------------ + + +def test_rights_are_not_shared_by_different_roles( + AllowedRecipientsRegistry, + owner, + stranger, + voting, + accounts, + bokkyPooBahsDateTimeContract, +): + deployer = owner + add_role_holder = accounts[6] + remove_role_holder = accounts[7] + set_limit_role_holder = accounts[8] + update_limit_role_holder = accounts[9] + + registry = deployer.deploy( + AllowedRecipientsRegistry, + voting, + [add_role_holder], + [remove_role_holder], + [set_limit_role_holder], + [update_limit_role_holder], + bokkyPooBahsDateTimeContract, + ) + assert registry.hasRole(registry.DEFAULT_ADMIN_ROLE(), voting) + + recipient = accounts[8].address + recipient_title = "New Allowed Recipient" + + for caller in [ + deployer, + remove_role_holder, + set_limit_role_holder, + update_limit_role_holder, + stranger, + ]: + with reverts(access_revert_message(caller, ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE)): + registry.addRecipient(recipient, recipient_title, {"from": caller}) + + for caller in [ + deployer, + add_role_holder, + set_limit_role_holder, + update_limit_role_holder, + stranger, + ]: + with reverts(access_revert_message(caller, REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE)): + registry.removeRecipient(recipient, {"from": caller}) + + for caller in [ + deployer, + add_role_holder, + remove_role_holder, + update_limit_role_holder, + stranger, + ]: + with reverts(access_revert_message(caller, SET_PARAMETERS_ROLE)): + registry.setLimitParameters(0, 1, {"from": caller}) + + with reverts(access_revert_message(caller, SET_PARAMETERS_ROLE)): + registry.setBokkyPooBahsDateTimeContract(ZERO_ADDRESS, {"from": caller}) + + with reverts(access_revert_message(caller, SET_PARAMETERS_ROLE)): + registry.unsafeSetSpentAmount(0, {"from": caller}) + + for caller in [ + deployer, + add_role_holder, + remove_role_holder, + set_limit_role_holder, + stranger, + ]: + with reverts(access_revert_message(caller, UPDATE_SPENT_AMOUNT_ROLE)): + registry.updateSpentAmount(1, {"from": caller}) + + +def test_multiple_role_holders(AllowedRecipientsRegistry, owner, voting, accounts, bokkyPooBahsDateTimeContract): + deployer = owner + add_role_holders = (accounts[2], accounts[3]) + remove_role_holders = (accounts[4], accounts[5]) + set_parameters_role_holders = (accounts[6], accounts[7]) + update_limit_role_holders = (accounts[8], accounts[9]) + + registry = deployer.deploy( + AllowedRecipientsRegistry, + voting, + add_role_holders, + remove_role_holders, + set_parameters_role_holders, + update_limit_role_holders, + bokkyPooBahsDateTimeContract, + ) + recipient_title = "New Allowed Recipient" + + for caller in accounts: + if not caller in add_role_holders: + with reverts(access_revert_message(caller, ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE)): + registry.addRecipient(caller, recipient_title, {"from": caller}) + + for recipient in accounts[0:5]: + registry.addRecipient(recipient, recipient_title, {"from": add_role_holders[0]}) + for recipient in accounts[5:10]: + registry.addRecipient(recipient, recipient_title, {"from": add_role_holders[1]}) + + for caller in accounts: + if caller in remove_role_holders: + registry.removeRecipient(caller, {"from": caller}) + else: + with reverts(access_revert_message(caller, REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE)): + registry.removeRecipient(caller, {"from": caller}) + + for caller in accounts: + if caller in set_parameters_role_holders: + registry.setLimitParameters(5, 1, {"from": caller}) + else: + with reverts(access_revert_message(caller, SET_PARAMETERS_ROLE)): + registry.setLimitParameters(5, 1, {"from": caller}) + with reverts(access_revert_message(caller, SET_PARAMETERS_ROLE)): + registry.setBokkyPooBahsDateTimeContract(ZERO_ADDRESS, {"from": caller}) + with reverts(access_revert_message(caller, SET_PARAMETERS_ROLE)): + registry.unsafeSetSpentAmount(0, {"from": caller}) + + for caller in accounts: + if caller in update_limit_role_holders: + registry.updateSpentAmount(1, {"from": caller}) + else: + with reverts(access_revert_message(caller, UPDATE_SPENT_AMOUNT_ROLE)): + registry.updateSpentAmount(1, {"from": caller}) + + +def test_access_stranger_cannot_set_limit_parameters(limits_checker, stranger): + (limits_checker, _, _) = limits_checker + + with reverts(access_revert_message(stranger, SET_PARAMETERS_ROLE)): + limits_checker.setLimitParameters(123, 1, {"from": stranger}) + + +def test_access_stranger_cannot_set_date_time_library(limits_checker, stranger): + (limits_checker, _, _) = limits_checker + + with reverts(access_revert_message(stranger, SET_PARAMETERS_ROLE)): + limits_checker.setBokkyPooBahsDateTimeContract(ZERO_ADDRESS, {"from": stranger}) + + +def test_access_stranger_cannot_set_date_time_library(limits_checker, stranger): + (limits_checker, _, _) = limits_checker + + with reverts(access_revert_message(stranger, SET_PARAMETERS_ROLE)): + limits_checker.unsafeSetSpentAmount(0, {"from": stranger}) + + +def test_access_stranger_cannot_update_spent_amount(limits_checker, stranger): + (limits_checker, _, _) = limits_checker + + with reverts(access_revert_message(stranger, UPDATE_SPENT_AMOUNT_ROLE)): + limits_checker.updateSpentAmount(123, {"from": stranger}) + + +# ------------ +# AllowedRecipientsRegistry logic +# ------------ + + +def test_set_date_time_contract(limits_checker): + (limits_checker, set_parameters_role_holder, _) = limits_checker + new_address = accounts[8] + assert limits_checker.bokkyPooBahsDateTimeContract() != new_address + tx = limits_checker.setBokkyPooBahsDateTimeContract(new_address, {"from": set_parameters_role_holder}) + assert limits_checker.bokkyPooBahsDateTimeContract() == new_address + assert_single_event( + tx, + "BokkyPooBahsDateTimeContractChanged", + {"_newAddress": new_address}, + ) + + +def test_fail_if_set_same_time_contract(limits_checker, accounts): + (limits_checker, set_parameters_role_holder, _) = limits_checker + current_address = limits_checker.bokkyPooBahsDateTimeContract() + with reverts("SAME_DATE_TIME_CONTRACT_ADDRESS"): + limits_checker.setBokkyPooBahsDateTimeContract(current_address, {"from": set_parameters_role_holder}) + + +def test_unsafe_set_spent_amount_when_spent_amount_exceeds_limit(limits_checker): + (limits_checker, set_parameters_role_holder, _) = limits_checker + + initial_limit = 100 * 10**18 + initial_duration = 3 + + limits_checker.setLimitParameters(initial_limit, initial_duration, {"from": set_parameters_role_holder}) + + current_limit, current_duration = limits_checker.getLimitParameters() + + assert current_limit == initial_limit + assert current_duration == initial_duration + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == 0 + + with reverts("ERROR_SPENT_AMOUNT_EXCEEDS_LIMIT"): + limits_checker.unsafeSetSpentAmount(initial_limit + 1, {"from": set_parameters_role_holder}) + + +def test_unsafe_set_spent_amount_when_new_spent_amount_the_same(limits_checker): + (limits_checker, set_parameters_role_holder, _) = limits_checker + + initial_limit = 100 * 10**18 + initial_duration = 3 + + limits_checker.setLimitParameters(initial_limit, initial_duration, {"from": set_parameters_role_holder}) + + current_limit, current_duration = limits_checker.getLimitParameters() + already_spent_amount = limits_checker.getPeriodState()["_alreadySpentAmount"] + + assert current_limit == initial_limit + assert current_duration == initial_duration + assert already_spent_amount == 0 + + tx = limits_checker.unsafeSetSpentAmount(already_spent_amount, {"from": set_parameters_role_holder}) + + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == already_spent_amount + + # validate that the event isn't logged cause the new value wasn't set + assert "SpentAmountChanged" not in tx.events + + +def test_unsafe_set_spent_amount(limits_checker): + (limits_checker, set_parameters_role_holder, _) = limits_checker + + initial_limit = 100 * 10**18 + initial_duration = 3 + + limits_checker.setLimitParameters(initial_limit, initial_duration, {"from": set_parameters_role_holder}) + + current_limit, current_duration = limits_checker.getLimitParameters() + + assert current_limit == initial_limit + assert current_duration == initial_duration + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == 0 + + new_spent_amount = current_limit // 2 + + tx = limits_checker.unsafeSetSpentAmount(new_spent_amount, {"from": set_parameters_role_holder}) + + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == new_spent_amount + assert tx.events["SpentAmountChanged"]["_newSpentAmount"] == new_spent_amount + + # validate that update works also when the spent amount is not zero + new_spent_amount = initial_limit + + tx = limits_checker.unsafeSetSpentAmount(new_spent_amount, {"from": set_parameters_role_holder}) + + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == new_spent_amount + assert tx.events["SpentAmountChanged"]["_newSpentAmount"] == new_spent_amount + + +def test_add_recipient(allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + recipient = accounts[8].address + + registry.addRecipient(recipient, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(recipient) + assert len(registry.getAllowedRecipients()) == 1 + assert registry.getAllowedRecipients()[0] == recipient + + +def test_add_recipient_with_empty_title(allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + recipient = accounts[8].address + + registry.addRecipient(recipient, "", {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(recipient) + assert len(registry.getAllowedRecipients()) == 1 + assert registry.getAllowedRecipients()[0] == recipient + + +def test_add_recipient_with_zero_address(allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + + registry.addRecipient(ZERO_ADDRESS, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(ZERO_ADDRESS) + assert len(registry.getAllowedRecipients()) == 1 + assert registry.getAllowedRecipients()[0] == ZERO_ADDRESS + + +def test_add_multiple_recipients(allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + recipient1 = accounts[8].address + recipient2 = accounts[9].address + + registry.addRecipient(recipient1, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + registry.addRecipient(recipient2, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(recipient1) + assert registry.isRecipientAllowed(recipient2) + assert len(registry.getAllowedRecipients()) == 2 + assert registry.getAllowedRecipients()[0] == recipient1 + assert registry.getAllowedRecipients()[1] == recipient2 + + +def test_fail_if_add_the_same_recipient(allowed_recipients_registry): + (registry, _, add_recipient_role_holder, _, _, _) = allowed_recipients_registry + recipient = accounts[8].address + + registry.addRecipient(recipient, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(recipient) + with reverts("RECIPIENT_ALREADY_ADDED_TO_ALLOWED_LIST"): + registry.addRecipient(recipient, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert len(registry.getAllowedRecipients()) == 1 + + +def test_remove_recipient(allowed_recipients_registry): + ( + registry, + _, + add_recipient_role_holder, + remove_recipient_role_holder, + _, + _, + ) = allowed_recipients_registry + recipient = accounts[8].address + + registry.addRecipient(recipient, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(recipient) + + registry.removeRecipient(recipient, {"from": remove_recipient_role_holder}) + + assert not registry.isRecipientAllowed(recipient) + + assert len(registry.getAllowedRecipients()) == 0 + + +def test_remove_not_last_recipient_in_the_list(allowed_recipients_registry): + ( + registry, + _, + add_recipient_role_holder, + remove_recipient_role_holder, + _, + _, + ) = allowed_recipients_registry + recipient1 = accounts[8].address + recipient2 = accounts[9].address + + registry.addRecipient(recipient1, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + registry.addRecipient(recipient2, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(recipient1) + assert registry.isRecipientAllowed(recipient2) + + registry.removeRecipient(recipient1, {"from": remove_recipient_role_holder}) + + assert registry.getAllowedRecipients() == [recipient2] + + +def test_fail_if_remove_recipient_from_empty_allowed_list(allowed_recipients_registry): + (registry, _, _, remove_recipient_role_holder, _, _) = allowed_recipients_registry + recipient = accounts[8].address + + assert 0 == len(registry.getAllowedRecipients()) + assert not registry.isRecipientAllowed(recipient) + + with reverts("RECIPIENT_NOT_FOUND_IN_ALLOWED_LIST"): + registry.removeRecipient(recipient, {"from": remove_recipient_role_holder}) + + assert len(registry.getAllowedRecipients()) == 0 + + +def test_fail_if_remove_not_allowed_recipient(allowed_recipients_registry): + ( + registry, + _, + add_recipient_role_holder, + remove_recipient_role_holder, + _, + _, + ) = allowed_recipients_registry + recipient1 = accounts[8].address + recipient2 = accounts[9].address + + registry.addRecipient(recipient1, RECIPIENT_TITLE, {"from": add_recipient_role_holder}) + + assert registry.isRecipientAllowed(recipient1) + + with reverts("RECIPIENT_NOT_FOUND_IN_ALLOWED_LIST"): + registry.removeRecipient(recipient2, {"from": remove_recipient_role_holder}) + + assert len(registry.getAllowedRecipients()) == 1 + assert registry.getAllowedRecipients()[0] == recipient1 + assert registry.isRecipientAllowed(recipient1) + assert not registry.isRecipientAllowed(recipient2) + + +# ------------ +# LimitsChecker logic +# ------------ + + +def test_set_limit_parameters_happy_path(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + _, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + now = datetime.now() + period_start = get_month_start_timestamp(now) + + tx = limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + assert_event_exists(tx, "CurrentPeriodAdvanced", {"_periodStartTimestamp": period_start}) + assert_event_exists( + tx, + "LimitsParametersChanged", + {"_limit": period_limit, "_periodDurationMonths": period_duration}, + ) + assert len(tx.events) == 2, f"must exist two events" + + advance_chain_time_to_beginning_of_the_next_period(period_duration) + assert limits_checker.getLimitParameters() == (period_limit, period_duration) + assert limits_checker.isUnderSpendableBalance(period_limit, 0) + + +def test_period_range_calculation_for_all_allowed_period_durations( + limits_checker_with_private_method_exposed, +): + ( + limits_checker, + set_parameters_role_holder, + _, + ) = limits_checker_with_private_method_exposed + + assert limits_checker.getLimitParameters()[1] == 0 + + period_limit = 0 + + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(1) + + # duration is iterated inside the test instead of test parametrization + # to check that period range is calculated correctly even if the contract + # state wasn't the initial state + for _ in range(24): + for duration in [1, 2, 3, 6, 12]: + limits_checker.setLimitParameters(period_limit, duration, {"from": set_parameters_role_holder}) + _, _, period_start, period_end = limits_checker.getPeriodState() + assert (period_start, period_end) == calc_period_range( + duration, chain.time() + ), f"incorrect range for period {duration}" + + chain.sleep(MAX_SECONDS_IN_MONTH // 2) + + +@pytest.mark.parametrize("period_duration", [0, 4, 5, 7, 8, 9, 10, 11, 13, 14, 100500]) +def test_fail_if_set_incorrect_period_durations(limits_checker, period_duration): + (limits_checker, set_parameters_role_holder, _) = limits_checker + + period_limit = 10**18 + with reverts("INVALID_PERIOD_DURATION"): + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + + +@pytest.mark.parametrize( + "period_duration,current_month,period_first_month", + [(1, i, calc_period_first_month(1, i)) for i in range(1, 13)] + + [(2, i, calc_period_first_month(2, i)) for i in range(1, 13)] + + [(3, i, calc_period_first_month(3, i)) for i in range(1, 13)] + + [(6, i, calc_period_first_month(6, i)) for i in range(1, 13)] + + [(12, i, calc_period_first_month(12, i)) for i in range(1, 13)], +) +def test_get_first_month_in_period_for_all_allowed_period_durations( + limits_checker_with_private_method_exposed, + period_duration, + current_month, + period_first_month, +): + ( + limits_checker, + set_parameters_role_holder, + _, + ) = limits_checker_with_private_method_exposed + + period_limit = 0 + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + + assert limits_checker.getFirstMonthInPeriodFromCurrentMonth(current_month) == period_first_month + + +def test_fail_if_set_limit_greater_than_max_limit(limits_checker): + (limits_checker, set_parameters_role_holder, _) = limits_checker + + period_limit, period_duration = 2**128, 1 + + # OK if 1 wei less the limit + limits_checker.setLimitParameters(period_limit - 1, period_duration, {"from": set_parameters_role_holder}) + + with reverts("TOO_LARGE_LIMIT"): + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + + +def test_limits_checker_views_in_next_period(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + + period_limit, period_duration = int(10e18), 1 + payout_amount = int(3e18) + spendable_balance = period_limit - payout_amount + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + limits_checker.updateSpentAmount(payout_amount, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable_balance + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == payout_amount + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == spendable_balance + + chain.sleep(MAX_SECONDS_IN_MONTH * period_duration) + + assert limits_checker.spendableBalance() == spendable_balance + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == payout_amount + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == spendable_balance + + +def test_update_spent_amount_within_the_limit(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + now = datetime.fromtimestamp(chain.time()) + period_start = get_month_start_timestamp(now) + period_end = get_month_start_timestamp(get_date_in_next_period(now, period_duration)) + + tx = limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + + spending = 2 * 10**18 + spendable = period_limit - spending + tx = limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.isUnderSpendableBalance(spendable, 0) + assert limits_checker.isUnderSpendableBalance(period_limit, period_duration * MAX_SECONDS_IN_MONTH) + assert_single_event( + tx, + "SpendableAmountChanged", + { + "_alreadySpentAmount": spending, + "_spendableBalance": spendable, + "_periodStartTimestamp": period_start, + "_periodEndTimestamp": period_end, + }, + ) + + +def test_update_spent_amount_precisely_to_the_limit_in_multiple_portions( + limits_checker, +): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + spending = 1 * 10**18 + spendable = period_limit - spending + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == spendable + assert limits_checker.isUnderSpendableBalance(spendable, 0) + assert limits_checker.isUnderSpendableBalance(period_limit, period_duration * MAX_SECONDS_IN_MONTH) + + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == 2 * spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == period_limit - 2 * spending + + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == period_limit + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == 0 + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + +def test_spending_amount_is_restored_in_the_next_period(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + spending = period_limit + spendable = period_limit - spending + + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + + chain.sleep(MAX_SECONDS_IN_MONTH * period_duration) + + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable + + +def test_fail_if_update_spent_amount_beyond_the_limit(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + spending = period_limit + 1 + + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + (_, spendable_balance, _, _) = limits_checker.getPeriodState() + + assert spendable_balance == period_limit + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + + +def test_spendable_amount_increased_if_limit_increased(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + spending = period_limit + spendable = period_limit - spending + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == spendable + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + new_period_limit = 2 * period_limit + new_spendable = spendable + (new_period_limit - period_limit) + limits_checker.setLimitParameters(new_period_limit, period_duration, {"from": set_parameters_role_holder}) + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == new_spendable + assert limits_checker.spendableBalance() == new_spendable + + limits_checker.updateSpentAmount(new_spendable, {"from": update_spent_amount_role_holder}) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + +def test_spendable_amount_if_limit_decreased_below_spent_amount(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + spending = 1 * 10**18 + spendable = period_limit - spending + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == spendable + + new_period_limit = spending - 1 + new_spendable = 0 + + limits_checker.setLimitParameters(new_period_limit, period_duration, {"from": set_parameters_role_holder}) + + # the already spent amount stays the same after the limit update + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == new_spendable + assert limits_checker.spendableBalance() == new_spendable + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + +def test_spendable_amount_if_limit_decreased_not_below_spent_amount(limits_checker): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit, period_duration = 3 * 10**18, 1 + + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + # set chain time to the beginning of month to prevent switch while the test is running + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + spending = 1 * 10**18 + spendable = period_limit - spending + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == spendable + + new_period_limit = 2 * spending + new_spendable = new_period_limit - spending + + limits_checker.setLimitParameters(new_period_limit, period_duration, {"from": set_parameters_role_holder}) + + # the already spent amount stays the same after the limit update + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == new_spendable + assert limits_checker.spendableBalance() == new_spendable + + limits_checker.updateSpentAmount(new_spendable, {"from": update_spent_amount_role_holder}) + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + +@pytest.mark.parametrize( + "initial_period_duration,new_period_duration", + [(3, 2), (3, 6), (12, 1), (1, 12)], +) +def test_spendable_amount_renewal_if_period_duration_changed( + limits_checker, initial_period_duration, new_period_duration +): + ( + limits_checker, + set_parameters_role_holder, + update_spent_amount_role_holder, + ) = limits_checker + period_limit = 3 * 10**18 + + limits_checker.setLimitParameters(period_limit, initial_period_duration, {"from": set_parameters_role_holder}) + advance_chain_time_to_beginning_of_the_next_period(max(initial_period_duration, new_period_duration)) + + spending = period_limit + spendable = period_limit - spending + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + assert limits_checker.spendableBalance() == spendable + assert limits_checker.getPeriodState()["_alreadySpentAmount"] == spending + assert limits_checker.getPeriodState()["_spendableBalanceInPeriod"] == spendable + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + limits_checker.setLimitParameters(period_limit, new_period_duration, {"from": set_parameters_role_holder}) + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + if new_period_duration > initial_period_duration: + # check after old period end spendable is not renewed + chain.sleep(MAX_SECONDS_IN_MONTH * (initial_period_duration)) + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + chain.sleep(MAX_SECONDS_IN_MONTH * (new_period_duration - initial_period_duration)) + else: + advance_chain_time_to_beginning_of_the_next_period(new_period_duration) + + limits_checker.updateSpentAmount(spending, {"from": update_spent_amount_role_holder}) + + with reverts("SUM_EXCEEDS_SPENDABLE_BALANCE"): + limits_checker.updateSpentAmount(1, {"from": update_spent_amount_role_holder}) + + +def test_fail_if_update_spent_amount_when_no_period_duration_set(limits_checker): + (limits_checker, _, update_spent_amount_role_holder) = limits_checker + + with reverts("INVALID_PERIOD_DURATION"): + limits_checker.updateSpentAmount(123, {"from": update_spent_amount_role_holder}) + + +@pytest.mark.parametrize( + "inputs, period_duration, expected_result", + [ + [ + [ + (2022, 1, 1), + (2022, 1, 1, 1), + (2022, 1, 15), + (2022, 1, 31, 23), + (2022, 1, 31, 23, 59, 59), + ], + 1, + (2022, 1, 1), + ], + [ + [ + (2022, 3, 1), + (2022, 3, 1, 1), + (2022, 4, 1), + (2022, 4, 30, 23), + (2022, 4, 30, 23, 59, 59), + ], + 2, + (2022, 3, 1), + ], + [ + [ + (2022, 4, 1), + (2022, 4, 1, 1), + (2022, 5, 15), + (2022, 6, 30, 23), + (2022, 6, 30, 23, 59, 59), + ], + 3, + (2022, 4, 1), + ], + [ + [ + (2022, 7, 1), + (2022, 7, 1, 1), + (2022, 10, 1), + (2022, 12, 31, 23), + (2022, 12, 31, 23, 59, 59), + ], + 6, + (2022, 7, 1), + ], + [ + [ + (2022, 1, 1), + (2022, 1, 1, 1), + (2022, 5, 15), + (2022, 12, 31, 23), + (2022, 12, 31, 23, 59, 59), + ], + 12, + (2022, 1, 1), + ], + ], +) +def test_period_start_from_timestamp( + limits_checker_with_private_method_exposed, inputs, period_duration, expected_result +): + ( + limits_checker, + set_parameters_role_holder, + _, + ) = limits_checker_with_private_method_exposed + period_limit = 3 * 10**18 + + expected_result = get_timestamp_from_date(*expected_result) + inputs = [get_timestamp_from_date(*date) for date in inputs] + + for timestamp in inputs: + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + assert limits_checker.getPeriodStartFromTimestamp(timestamp) == expected_result + + assert limits_checker.getPeriodStartFromTimestamp(inputs[0] - 3600) < expected_result # 1 hour before the period + assert limits_checker.getPeriodStartFromTimestamp(inputs[0] - 1) < expected_result # second before the period + assert ( + limits_checker.getPeriodStartFromTimestamp(inputs[len(inputs) - 1] + 1) > expected_result + ) # second after the period + assert ( + limits_checker.getPeriodStartFromTimestamp(inputs[len(inputs) - 1] + 3600) > expected_result + ) # hour after the period + + +@pytest.mark.parametrize( + "inputs, period_duration, expected_result", + [ + [ + [ + (2022, 1, 1), + (2022, 1, 1, 1), + (2022, 1, 15), + (2022, 1, 31, 23), + (2022, 1, 31, 23, 59, 59), + ], + 1, + (2022, 2, 1), + ], + [ + [ + (2022, 3, 1), + (2022, 3, 1, 1), + (2022, 4, 1), + (2022, 4, 30, 23), + (2022, 4, 30, 23, 59, 59), + ], + 2, + (2022, 5, 1), + ], + [ + [ + (2022, 4, 1), + (2022, 4, 1, 1), + (2022, 5, 15), + (2022, 6, 30, 23), + (2022, 6, 30, 23, 59, 59), + ], + 3, + (2022, 7, 1), + ], + [ + [ + (2022, 7, 1), + (2022, 7, 1, 1), + (2022, 10, 1), + (2022, 12, 31, 23), + (2022, 12, 31, 23, 59, 59), + ], + 6, + (2023, 1, 1), + ], + [ + [ + (2022, 1, 1), + (2022, 1, 1, 1), + (2022, 5, 15), + (2022, 12, 31, 23), + (2022, 12, 31, 23, 59, 59), + ], + 12, + (2023, 1, 1), + ], + ], +) +def test_period_end_from_timestamp( + limits_checker_with_private_method_exposed, inputs, period_duration, expected_result +): + ( + limits_checker, + set_parameters_role_holder, + _, + ) = limits_checker_with_private_method_exposed + period_limit = 3 * 10**18 + + expected_result = get_timestamp_from_date(*expected_result) + inputs = [get_timestamp_from_date(*date) for date in inputs] + + for timestamp in inputs: + limits_checker.setLimitParameters(period_limit, period_duration, {"from": set_parameters_role_holder}) + assert limits_checker.getPeriodEndFromTimestamp(timestamp) == expected_result + + assert limits_checker.getPeriodEndFromTimestamp(inputs[0] - 3600) < expected_result # hour before the period + assert limits_checker.getPeriodEndFromTimestamp(inputs[0] - 1) < expected_result # second before the period + assert ( + limits_checker.getPeriodEndFromTimestamp(inputs[len(inputs) - 1] + 2) > expected_result + ) # second after the period + assert ( + limits_checker.getPeriodEndFromTimestamp(inputs[len(inputs) - 1] + 3600) > expected_result + ) # hour after the period diff --git a/tests/test_aragon_acl.py b/tests/test_aragon_acl.py new file mode 100644 index 00000000..ea3e9f8f --- /dev/null +++ b/tests/test_aragon_acl.py @@ -0,0 +1,90 @@ +from brownie import web3, reverts + +TEST_ROLE = web3.keccak(text="STAKING_MODULE_MANAGE_ROLE").hex() +from utils.permission_parameters import Op, Param + + +def test_aragon_acl_grant_role(acl, voting, stranger): + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + + acl.createPermission(stranger, voting, TEST_ROLE, voting, {"from": voting}) + + assert acl.hasPermission(stranger, voting, TEST_ROLE) == True + assert acl.getPermissionParamsLength(stranger, voting, TEST_ROLE) == 0 + + +def test_aragon_acl_role_with_permission(acl, voting, stranger): + "Checks Aragon ACL permissions granting, overriding and show what could be checked to get current permissions state" + + permission_param = Param(0, Op.EQ, 3).to_uint256() + + # Test stranger has no roles + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + + # Create and grant role with params (0, 1, 3) + acl.createPermission(voting, voting, TEST_ROLE, voting, {"from": voting}) + acl.grantPermissionP(stranger, voting, TEST_ROLE, [permission_param], {"from": voting}) + + # Test role (0, 1, 3) + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + assert acl.hasPermission["address,address,bytes32,uint[]"](stranger, voting, TEST_ROLE, [permission_param]) == True + assert acl.getPermissionParamsLength(stranger, voting, TEST_ROLE) == 1 + assert acl.getPermissionParam(stranger, voting, TEST_ROLE, 0) == (0, 1, 3) + + # Revoke role (0, 1, 3) + acl.revokePermission(stranger, voting, TEST_ROLE, {"from": voting}) + + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + assert acl.hasPermission["address,address,bytes32,uint[]"](stranger, voting, TEST_ROLE, [permission_param]) == False + assert acl.getPermissionParamsLength(stranger, voting, TEST_ROLE) == 0 + with reverts(): + acl.getPermissionParam(stranger, voting, TEST_ROLE, 0) + + # Grant role with params (0, 1, 4) + new_permission_param = Param(0, Op.EQ, 4).to_uint256() + + acl.grantPermissionP(stranger, voting, TEST_ROLE, [new_permission_param], {"from": voting}) + + # Test role (0, 1, 4) + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + assert ( + acl.hasPermission["address,address,bytes32,uint[]"](stranger, voting, TEST_ROLE, [new_permission_param]) == True + ) + assert acl.getPermissionParamsLength(stranger, voting, TEST_ROLE) == 1 + assert acl.getPermissionParam(stranger, voting, TEST_ROLE, 0) == (0, 1, 4) + + +def test_aragon_acl_two_roles_with_different_params(acl, voting, stranger): + "Checks how granting different parameterized permissions overrides themselves" + # Grant role with params (0, 1, 3) + permission = (0, 1, 3) + permission_param = Param(0, Op.EQ, 3).to_uint256() + + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + + acl.createPermission(voting, voting, TEST_ROLE, voting, {"from": voting}) + acl.grantPermissionP(stranger, voting, TEST_ROLE, [permission_param], {"from": voting}) + + # Test role (0, 1, 3) + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + assert acl.hasPermission["address,address,bytes32,uint[]"](stranger, voting, TEST_ROLE, [permission_param]) == True + assert acl.getPermissionParamsLength(stranger, voting, TEST_ROLE) == 1 + assert acl.getPermissionParam(stranger, voting, TEST_ROLE, 0) == permission + + # Grant role with params (0, 1, 4) + new_permission = (0, 1, 4) + new_permission_param = Param(0, Op.EQ, 4).to_uint256() + + acl.grantPermissionP(stranger, voting, TEST_ROLE, [new_permission_param], {"from": voting}) + + # Test role (0, 1, 4) + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + assert ( + acl.hasPermission["address,address,bytes32,uint[]"](stranger, voting, TEST_ROLE, [new_permission_param]) == True + ) + assert acl.getPermissionParamsLength(stranger, voting, TEST_ROLE) == 1 + assert acl.getPermissionParam(stranger, voting, TEST_ROLE, 0) == new_permission + + # Test role (0, 1, 3) + assert acl.hasPermission(stranger, voting, TEST_ROLE) == False + assert acl.hasPermission["address,address,bytes32,uint[]"](stranger, voting, TEST_ROLE, [permission_param]) == False diff --git a/tests/test_bokky_poo_bahs_date-time-library.py b/tests/test_bokky_poo_bahs_date-time-library.py new file mode 100644 index 00000000..edc5b7f2 --- /dev/null +++ b/tests/test_bokky_poo_bahs_date-time-library.py @@ -0,0 +1,154 @@ +import pytest + +from datetime import datetime, timezone +from dateutil.relativedelta import relativedelta +from brownie import interface +from brownie.test import given, strategy +from hypothesis import Verbosity, settings +from utils.test_helpers import get_timestamp_from_date + + +class Progress: + def __init__(self, max_value, current_value=0): + self.max_value = max_value + self.current_value = current_value + + def count(self, inc=1): + self.current_value += 1 + + def __str__(self): + p = round(100 * self.current_value / self.max_value) + return f"Progress: {str(p).rjust(3)}% - [" + "." * int(p / 5) + " " * (20 - int(p / 5)) + "]" + + +class ProgressFixture: + def __init__(self): + self._instances = {} + + def get_or_create_instance(self, name, max_value): + if name not in self._instances: + self._instances[name] = Progress(max_value) + return self._instances[name] + + +@pytest.fixture(scope="module") +def progress(): + return ProgressFixture() + + +@pytest.mark.parametrize( + "date", + [(1970, 1, 1), (2024, 2, 29), (2023, 1, 1), (2023, 1, 1), (2022, 12, 31)], +) +def test_timestamp_to_date(date_time_library, date): + assert date_time_library.timestampToDate(get_timestamp_from_date(*date)) == date + + +@pytest.mark.parametrize( + "start_date,end_date", + [[(2020, 1, 1), (2025, 1, 1)]], +) +def test_timestamp_to_date_automated(date_time_library, start_date, end_date): + current_date = datetime(*start_date, tzinfo=timezone.utc) + + while datetime.timestamp(current_date) < get_timestamp_from_date(*end_date): + assert date_time_library.timestampToDate(datetime.timestamp(current_date)) == ( + current_date.year, + current_date.month, + current_date.day, + ) + + current_date += relativedelta(days=+1) + + +@given( + timestamp=strategy( + "int", + min_value=get_timestamp_from_date(2022, 1, 1), + max_value=get_timestamp_from_date(2030, 1, 1), + ) +) +@settings(max_examples=5000, verbosity=Verbosity.quiet) +def test_property_based_timestamp_to_date(date_time_library, progress, timestamp): + progress_counter = progress.get_or_create_instance("test_property_based_timestamp_to_date", max_value=5000) + current_date = datetime.fromtimestamp(timestamp, tz=timezone.utc) + assert date_time_library.timestampToDate(timestamp) == ( + current_date.year, + current_date.month, + current_date.day, + ) + progress_counter.count() + if progress_counter.current_value % 250 == 0: + print(progress_counter) + + +@pytest.mark.parametrize( + "date", + [ + (1970, 1, 1), + (2024, 2, 29), + (2023, 1, 1), + (2022, 12, 31), + ], +) +# This method always returns timestamp of start of the day +def test_timestamp_from_date(date_time_library, date): + assert date_time_library.timestampFromDate(*date) == get_timestamp_from_date(*date) + + +@pytest.mark.parametrize( + "start_date,end_date", + [[(2020, 1, 1), (2025, 1, 1)]], +) +def test_timestamp_from_date_automated(date_time_library, start_date, end_date): + current_date = datetime(*start_date, tzinfo=timezone.utc) + + while datetime.timestamp(current_date) < get_timestamp_from_date(*end_date): + assert date_time_library.timestampFromDate( + current_date.year, + current_date.month, + current_date.day, + ) == datetime.timestamp(current_date) + + current_date += relativedelta(days=+1) + + +TEST_START_DATE = datetime(2022, 1, 1, tzinfo=timezone.utc) +TEST_END_DATE = datetime(2030, 1, 1, tzinfo=timezone.utc) + + +@given( + days_shift=strategy("int", min_value=0, max_value=(TEST_END_DATE - TEST_START_DATE).days), +) +@settings(max_examples=5000, verbosity=Verbosity.quiet) +def test_property_based_timestamp_from_date(date_time_library, progress, days_shift): + progress_counter = progress.get_or_create_instance("test_property_based_timestamp_from_date", max_value=5000) + + date = TEST_START_DATE + relativedelta(days=+days_shift) + assert date_time_library.timestampFromDate(date.year, date.month, date.day) == date.timestamp() + + progress_counter.count() + if progress_counter.current_value % 250 == 0: + print(progress_counter) + + +@pytest.mark.parametrize( + "start_date, months_to_add", + [((2020, 1, 1), months) for months in [1, 2, 3, 6, 8, 12, 24]] # First day of month + + [((2020, 1, 31), months) for months in [1, 2, 3, 6, 8, 12, 24]], # Last day of month +) +def test_add_month(date_time_library, start_date, months_to_add): + current_point = datetime(*start_date, tzinfo=timezone.utc) + + num_subsequent_add_months_calls = 120 + for _ in range(num_subsequent_add_months_calls): + assert datetime.timestamp(current_point + relativedelta(months=+months_to_add)) == date_time_library.addMonths( + datetime.timestamp(current_point), months_to_add + ) + + current_point += relativedelta(months=+1) + + +@pytest.fixture(scope="module") +def date_time_library(bokkyPooBahsDateTimeContract): + return interface.IBokkyPooBahsDateTimeContract(bokkyPooBahsDateTimeContract) diff --git a/tests/test_easy_track.py b/tests/test_easy_track.py index 80bbdf79..a8c3ce80 100644 --- a/tests/test_easy_track.py +++ b/tests/test_easy_track.py @@ -1,9 +1,10 @@ +import pytest import constants from brownie.network.state import Chain from brownie import reverts, ZERO_ADDRESS from utils.evm_script import encode_call_script from utils.test_helpers import ( - access_controll_revert_message, + access_revert_message, CANCEL_ROLE, PAUSE_ROLE, UNPAUSE_ROLE, @@ -50,23 +51,17 @@ def test_create_motion_evm_script_factory_not_found(owner, stranger, easy_track) easy_track.createMotion(stranger, b"", {"from": owner}) -def test_create_motion_has_no_permissions( - voting, stranger, easy_track, evm_script_factory_stub -): +def test_create_motion_has_no_permissions(voting, stranger, easy_track, evm_script_factory_stub): "Must revert with message 'HAS_NO_PERMISSIONS' if evm script" "tries to call method not listed in permissions" wrong_permissions = ZERO_ADDRESS + "11111111" - easy_track.addEVMScriptFactory( - evm_script_factory_stub, wrong_permissions, {"from": voting} - ) + easy_track.addEVMScriptFactory(evm_script_factory_stub, wrong_permissions, {"from": voting}) assert evm_script_factory_stub.DEFAULT_PERMISSIONS() != wrong_permissions with reverts("HAS_NO_PERMISSIONS"): easy_track.createMotion(evm_script_factory_stub, b"", {"from": stranger}) -def test_create_motion_motions_limit_reached( - voting, stranger, easy_track, evm_script_factory_stub -): +def test_create_motion_motions_limit_reached(voting, stranger, easy_track, evm_script_factory_stub): "Must revert with message 'MOTIONS_LIMIT_REACHED' when motionsCountLimit reached" easy_track.setMotionsCountLimit(1, {"from": voting}) assert easy_track.motionsCountLimit() == 1 @@ -83,9 +78,7 @@ def test_create_motion_motions_limit_reached( easy_track.createMotion(evm_script_factory_stub, b"", {"from": stranger}) -def test_create_motion( - owner, voting, easy_track, evm_script_factory_stub, node_operators_registry_stub -): +def test_create_motion(owner, voting, easy_track, evm_script_factory_stub): "Must create new motion with correct data and emit" "MotionCreated event if called by easy track" chain = Chain() @@ -108,10 +101,7 @@ def test_create_motion( assert tx.events["MotionCreated"]["_creator"] == owner assert tx.events["MotionCreated"]["_evmScriptFactory"] == evm_script_factory_stub assert tx.events["MotionCreated"]["_evmScriptCallData"] == call_data - assert ( - tx.events["MotionCreated"]["_evmScript"] - == evm_script_factory_stub.DEFAULT_EVM_SCRIPT() - ) + assert tx.events["MotionCreated"]["_evmScript"] == evm_script_factory_stub.DEFAULT_EVM_SCRIPT() # validate motion data motions = easy_track.getMotions() @@ -124,13 +114,9 @@ def test_create_motion( assert new_motion[3] == constants.MIN_MOTION_DURATION # duration assert new_motion[4] == chain[-1].timestamp # startDate assert new_motion[5] == chain[-1].number # snapshotBlock - assert ( - new_motion[6] == constants.DEFAULT_OBJECTIONS_THRESHOLD - ) # objectionsThreshold + assert new_motion[6] == constants.DEFAULT_OBJECTIONS_THRESHOLD # objectionsThreshold assert new_motion[7] == 0 # objectionsAmount - assert ( - new_motion[8] == evm_script_factory_stub.DEFAULT_EVM_SCRIPT_HASH() - ) # evmScriptHash + assert new_motion[8] == evm_script_factory_stub.DEFAULT_EVM_SCRIPT_HASH() # evmScriptHash ######## @@ -144,9 +130,7 @@ def test_cancel_motion_not_found(owner, easy_track): easy_track.cancelMotion(1, {"from": owner}) -def test_cancel_motion_not_creator( - owner, voting, stranger, easy_track, evm_script_factory_stub -): +def test_cancel_motion_not_creator(owner, voting, stranger, easy_track, evm_script_factory_stub): "Must revert with message 'NOT_CREATOR' if canceled not by owner" # add evm script factory to create motions easy_track.addEVMScriptFactory( @@ -191,9 +175,7 @@ def test_cancel_motion(voting, stranger, easy_track, evm_script_factory_stub): assert tx.events["MotionCanceled"]["_motionId"] == motions[0][0] -def test_cancel_motion_in_random_order( - owner, voting, easy_track, evm_script_factory_stub -): +def test_cancel_motion_in_random_order(owner, voting, easy_track, evm_script_factory_stub): "Must remove correct motions from list of active motions" "whe cancelMotion called with motion id in random order" # add evm script factory to create motions @@ -250,9 +232,7 @@ def test_enact_motion_when_paused(stranger, voting, easy_track): easy_track.enactMotion(1, b"", {"from": stranger}) -def test_enact_motion_when_motion_not_passed( - owner, voting, easy_track, evm_script_factory_stub -): +def test_enact_motion_when_motion_not_passed(owner, voting, easy_track, evm_script_factory_stub): "Must revert with message 'MOTION_NOT_PASSED' if called with motion id" "created less than motionDuration time ago" # add evm script factory to create motions @@ -276,19 +256,12 @@ def test_enact_motion_when_motion_not_passed( ) -def test_enact_motion_unexpected_evm_script( - owner, voting, easy_track, evm_script_factory_stub -): +def test_enact_motion_unexpected_evm_script(owner, voting, easy_track, evm_script_factory_stub): "Must revert with message 'UNEXPECTED_EVM_SCRIPT' when hash of enact script" "not equal to script created on motion creation step" # add evm script factory to create motions - permissions = ( - evm_script_factory_stub.address - + evm_script_factory_stub.setEVMScript.signature[2:] - ) - easy_track.addEVMScriptFactory( - evm_script_factory_stub, permissions, {"from": voting} - ) + permissions = evm_script_factory_stub.address + evm_script_factory_stub.setEVMScript.signature[2:] + easy_track.addEVMScriptFactory(evm_script_factory_stub, permissions, {"from": voting}) evm_script_factory_stub.setEVMScript( encode_call_script( [ @@ -329,9 +302,7 @@ def test_enact_motion_unexpected_evm_script( ) -def test_enact_motion( - owner, voting, easy_track, evm_script_factory_stub, evm_script_executor_stub -): +def test_enact_motion(owner, voting, easy_track, evm_script_factory_stub, evm_script_executor_stub): "Must remove motion from list of active motions, execute EVM script created by EVMScriptFactory" "contained in created motion and emits event MotionEnacted(_moitonId)" # add evm script factory to create motions @@ -342,6 +313,8 @@ def test_enact_motion( ) assert easy_track.isEVMScriptFactory(evm_script_factory_stub) + easy_track.setEVMScriptExecutor(evm_script_executor_stub, {"from": voting}) + # create new motion tx = easy_track.createMotion(evm_script_factory_stub, b"", {"from": owner}) motions = easy_track.getMotions() @@ -355,9 +328,7 @@ def test_enact_motion( assert evm_script_executor_stub.evmScript() == "0x" # enact motion - tx = easy_track.enactMotion( - motions[0][0], tx.events["MotionCreated"]["_evmScriptCallData"], {"from": owner} - ) + tx = easy_track.enactMotion(motions[0][0], tx.events["MotionCreated"]["_evmScriptCallData"], {"from": owner}) # validate that motion was removed from list of active motions assert len(easy_track.getMotions()) == 0 @@ -366,10 +337,7 @@ def test_enact_motion( assert tx.events["MotionEnacted"]["_motionId"] == motions[0][0] # validate that was passed correct evm script to evm_script_executor_stub - assert ( - evm_script_executor_stub.evmScript() - == evm_script_factory_stub.DEFAULT_EVM_SCRIPT() - ) + assert evm_script_executor_stub.evmScript() == evm_script_factory_stub.DEFAULT_EVM_SCRIPT() ######## @@ -383,14 +351,13 @@ def test_object_to_motion_motion_not_found(owner, easy_track): easy_track.objectToMotion(1, {"from": owner}) +@pytest.mark.usefixtures("distribute_holder_balance") def test_object_to_motion_multiple_times( owner, voting, ldo_holders, - ldo, easy_track, evm_script_factory_stub, - distribute_holder_balance, ): "Must revert with message: 'ALREADY_OBJECTED' if sender already objected the motion with the given id" # add evm script factory to create motions @@ -472,14 +439,11 @@ def test_object_to_motion_by_tokens_holder( assert tx.events["MotionObjected"]["_motionId"] == motion[0] assert tx.events["MotionObjected"]["_objector"] == ldo_holders[0] assert tx.events["MotionObjected"]["_weight"] == holder_balance - assert ( - tx.events["MotionObjected"]["_newObjectionsAmount"] == motion[7] - ) # objectionsAmount - assert ( - tx.events["MotionObjected"]["_newObjectionsAmountPct"] == holder_part - ) # objectionsAmountPct + assert tx.events["MotionObjected"]["_newObjectionsAmount"] == motion[7] # objectionsAmount + assert tx.events["MotionObjected"]["_newObjectionsAmountPct"] == holder_part # objectionsAmountPct +@pytest.mark.usefixtures("distribute_holder_balance") def test_object_to_motion_rejected( owner, voting, @@ -487,7 +451,6 @@ def test_object_to_motion_rejected( ldo, easy_track, evm_script_factory_stub, - distribute_holder_balance, ): "Must remove motion from list of active motions" "and emit ObjectionSent(_motionId,_objector,_weight,_newObjectionsAmount,_newObjectionsAmountPct)" @@ -510,11 +473,7 @@ def test_object_to_motion_rejected( tx = easy_track.objectToMotion(1, {"from": ldo_holders[2]}) # 0.6 % objections assert len(easy_track.getMotions()) == 0 - objections_amount = ( - ldo.balanceOf(ldo_holders[0]) - + ldo.balanceOf(ldo_holders[1]) - + ldo.balanceOf(ldo_holders[2]) - ) + objections_amount = ldo.balanceOf(ldo_holders[0]) + ldo.balanceOf(ldo_holders[1]) + ldo.balanceOf(ldo_holders[2]) objections_amount_pct = 10000 * objections_amount / ldo.totalSupply() # validate that events was emitted @@ -523,20 +482,14 @@ def test_object_to_motion_rejected( assert tx.events["MotionObjected"]["_objector"] == ldo_holders[2] assert tx.events["MotionObjected"]["_weight"] == ldo.balanceOf(ldo_holders[2]) assert tx.events["MotionObjected"]["_newObjectionsAmount"] == objections_amount - assert ( - tx.events["MotionObjected"]["_newObjectionsAmountPct"] == objections_amount_pct - ) + assert tx.events["MotionObjected"]["_newObjectionsAmountPct"] == objections_amount_pct assert tx.events["MotionRejected"]["_motionId"] == 1 -def test_object_to_motion_edge_case( - owner, stranger, agent, ldo, voting, easy_track, evm_script_factory_stub -): +def test_object_to_motion_edge_case(owner, stranger, agent, ldo, voting, easy_track, evm_script_factory_stub): "Must reject motion only if objections threshold was reached" - objections_threshold_amount = ( - int(easy_track.objectionsThreshold() * ldo.totalSupply() // 10000) - 1 - ) + objections_threshold_amount = int(easy_track.objectionsThreshold() * ldo.totalSupply() // 10000) - 1 ldo.transfer(owner, objections_threshold_amount, {"from": agent}) ldo.transfer(stranger, 1, {"from": agent}) @@ -568,18 +521,15 @@ def test_object_to_motion_edge_case( def test_cancel_motions_called_without_permissions(stranger, easy_track): "Must revert with correct Access Control message if called" "by address without role 'CANCEL_ROLE'" - with reverts(access_controll_revert_message(stranger, CANCEL_ROLE)): + with reverts(access_revert_message(stranger, CANCEL_ROLE)): easy_track.cancelMotions([], {"from": stranger}) def test_cancel_motions( owner, voting, - stranger, easy_track, evm_script_factory_stub, - finance, - node_operators_registry_stub, ): "Must cancel all motions in the list. Emits MotionCanceled(_motionId) event for each canceled motion." "If motion with passed id doesn't exists skip it and doesn't emit event" @@ -622,7 +572,7 @@ def test_cancel_motions( def test_cancel_all_motions_called_by_stranger(stranger, easy_track): "Must revert with correct Access Control message if called" "by address without role 'CANCEL_ROLE'" - with reverts(access_controll_revert_message(stranger, CANCEL_ROLE)): + with reverts(access_revert_message(stranger, CANCEL_ROLE)): easy_track.cancelAllMotions({"from": stranger}) @@ -659,22 +609,17 @@ def test_cancel_all_motions(owner, voting, easy_track, evm_script_factory_stub): def test_set_evm_script_executor_called_by_stranger(stranger, easy_track): "Must revert with correct Access Control message if called" "by address without role 'DEFAULT_ADMIN_ROLE'" - with reverts(access_controll_revert_message(stranger)): + with reverts(access_revert_message(stranger)): easy_track.setEVMScriptExecutor(ZERO_ADDRESS, {"from": stranger}) -def test_set_evm_script_executor_called_by_owner( - accounts, voting, easy_track, evm_script_executor, evm_script_executor_stub -): +def test_set_evm_script_executor_called_by_owner(voting, easy_track, evm_script_executor, evm_script_executor_stub): "Must set new EVMScriptExecutor and emit EVMScriptExecutorChanged(_evmScriptExecutor) event" - assert easy_track.evmScriptExecutor() == evm_script_executor_stub - tx = easy_track.setEVMScriptExecutor(evm_script_executor, {"from": voting}) - assert ( - tx.events["EVMScriptExecutorChanged"]["_evmScriptExecutor"] - == evm_script_executor - ) assert easy_track.evmScriptExecutor() == evm_script_executor + tx = easy_track.setEVMScriptExecutor(evm_script_executor_stub, {"from": voting}) + assert tx.events["EVMScriptExecutorChanged"]["_evmScriptExecutor"] == evm_script_executor_stub + assert easy_track.evmScriptExecutor() == evm_script_executor_stub ######## @@ -686,7 +631,7 @@ def test_pause_called_without_permissions(stranger, easy_track): "Must revert with correct Access Control message if called" "by address without role 'PAUSE_ROLE'" assert not easy_track.paused() - with reverts(access_controll_revert_message(stranger, PAUSE_ROLE)): + with reverts(access_revert_message(stranger, PAUSE_ROLE)): easy_track.pause({"from": stranger}) assert not easy_track.paused() @@ -719,7 +664,7 @@ def test_unpause_called_without_permissions(voting, stranger, easy_track): "by address without role 'UNPAUSE_ROLE'" easy_track.pause({"from": voting}) assert easy_track.paused() - with reverts(access_controll_revert_message(stranger, UNPAUSE_ROLE)): + with reverts(access_revert_message(stranger, UNPAUSE_ROLE)): easy_track.unpause({"from": stranger}) assert easy_track.paused() @@ -746,27 +691,21 @@ def test_unpause_called_with_permissions(voting, easy_track): ######## +@pytest.mark.usefixtures("distribute_holder_balance") def test_can_object_to_motion( owner, voting, stranger, ldo_holders, - ldo, easy_track, evm_script_factory_stub, - distribute_holder_balance, ): "Must return False if caller has no governance tokens or if he has already voted." "Returns True in other cases" # add evm script factory to create motions§ - permissions = ( - evm_script_factory_stub.address - + evm_script_factory_stub.setEVMScript.signature[2:] - ) - easy_track.addEVMScriptFactory( - evm_script_factory_stub, permissions, {"from": voting} - ) + permissions = evm_script_factory_stub.address + evm_script_factory_stub.setEVMScript.signature[2:] + easy_track.addEVMScriptFactory(evm_script_factory_stub, permissions, {"from": voting}) evm_script = encode_call_script( [ ( diff --git a/tests/test_evm_script_executor.py b/tests/test_evm_script_executor.py index 4556b805..677e70d8 100644 --- a/tests/test_evm_script_executor.py +++ b/tests/test_evm_script_executor.py @@ -1,5 +1,5 @@ from brownie import reverts -from eth_abi import encode_single +from eth_abi import encode from utils.evm_script import encode_call_script import constants @@ -13,18 +13,14 @@ def test_deploy(owner, easy_track, calls_script, EVMScriptExecutor): assert contract.easyTrack() == easy_track -def test_deploy_calls_script_not_contract( - owner, accounts, easy_track, EVMScriptExecutor -): +def test_deploy_calls_script_not_contract(owner, accounts, easy_track, EVMScriptExecutor): "Must revert with message 'CALLS_SCRIPT_IS_NOT_CONTRACT'" not_contract = accounts[6] with reverts("CALLS_SCRIPT_IS_NOT_CONTRACT"): owner.deploy(EVMScriptExecutor, not_contract, easy_track) -def test_deploy_easy_track_not_contract( - owner, accounts, calls_script, EVMScriptExecutor -): +def test_deploy_easy_track_not_contract(owner, accounts, calls_script, EVMScriptExecutor): "Must revert with message 'EASY_TRACK_IS_NOT_CONTRACT'" not_contract = accounts[6] with reverts("EASY_TRACK_IS_NOT_CONTRACT"): @@ -46,7 +42,7 @@ def test_execute_evm_script_revert_msg( increase_node_operator_staking_limit.address, increase_node_operator_staking_limit.createEVMScript.encode_input( node_operator, - "0x" + encode_single("(uint256,uint256)", [1, 500]).hex(), + "0x" + encode(["uint256", "uint256"], [1, 500]).hex(), ), ) ] @@ -55,27 +51,20 @@ def test_execute_evm_script_revert_msg( ) -def test_execute_evm_script_output( - easy_track, evm_script_executor, node_operators_registry_stub -): +def test_execute_evm_script_output(easy_track, evm_script_executor, node_operators_registry_stub): "Must return empty bytes and emit ScriptExecuted(_caller, _evmScript) event" assert node_operators_registry_stub.stakingLimit() == 200 evm_script = encode_call_script( [ ( node_operators_registry_stub.address, - node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input( - 1, 500 - ), + node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input(1, 500), ) ] ) # validate return value - assert ( - evm_script_executor.executeEVMScript.call(evm_script, {"from": easy_track}) - == "0x" - ) + assert evm_script_executor.executeEVMScript.call(evm_script, {"from": easy_track}) == "0x" tx = evm_script_executor.executeEVMScript(evm_script, {"from": easy_track}) @@ -85,9 +74,7 @@ def test_execute_evm_script_output( assert node_operators_registry_stub.stakingLimit() == 500 -def test_execute_evm_script_caller_validation( - stranger, easy_track, evm_script_executor, node_operators_registry_stub -): +def test_execute_evm_script_caller_validation(stranger, easy_track, evm_script_executor, node_operators_registry_stub): "Must accept calls to executeEVMScript only from EasyTrack contracts" with reverts("CALLER_IS_FORBIDDEN"): evm_script_executor.executeEVMScript("0x", {"from": stranger}) @@ -96,9 +83,7 @@ def test_execute_evm_script_caller_validation( [ ( node_operators_registry_stub.address, - node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input( - 1, 500 - ), + node_operators_registry_stub.setNodeOperatorStakingLimit.encode_input(1, 500), ) ] ) @@ -114,9 +99,7 @@ def test_set_easy_track_called_by_stranger(accounts, stranger, evm_script_execut evm_script_executor.setEasyTrack(new_easy_track, {"from": stranger}) -def test_set_easy_track_called_by_owner( - accounts, owner, ldo, voting, evm_script_executor, easy_track, EasyTrack -): +def test_set_easy_track_called_by_owner(accounts, owner, ldo, voting, evm_script_executor, easy_track, EasyTrack): "Must set new easyTrack value and emit EasyTrackChanged(address _previousEasyTrack, address _newEasyTrack) event" assert evm_script_executor.easyTrack() == easy_track diff --git a/tests/test_evm_script_factories_registry.py b/tests/test_evm_script_factories_registry.py index 9880fc3a..3e55cd7d 100644 --- a/tests/test_evm_script_factories_registry.py +++ b/tests/test_evm_script_factories_registry.py @@ -1,6 +1,6 @@ import pytest from brownie import reverts -from utils.test_helpers import access_controll_revert_message +from utils.test_helpers import access_revert_message @pytest.fixture(scope="module") @@ -20,38 +20,26 @@ def test_add_evm_script_factory_called_without_permissions( ): "Must revert with correct Access Control message if called by address without 'DEFAULT_ADMIN_ROLE'" permissions = stranger.address + "ffccddee" - with reverts(access_controll_revert_message(stranger)): - evm_script_factories_registry.addEVMScriptFactory( - stranger, permissions, {"from": stranger} - ) + with reverts(access_revert_message(stranger)): + evm_script_factories_registry.addEVMScriptFactory(stranger, permissions, {"from": stranger}) -def test_add_evm_script_factory_empty_permissions( - owner, stranger, evm_script_factories_registry -): +def test_add_evm_script_factory_empty_permissions(owner, stranger, evm_script_factories_registry): "Must revert with message 'INVALID_PERMISSIONS' if called with empty permissions" with reverts("INVALID_PERMISSIONS"): - evm_script_factories_registry.addEVMScriptFactory( - stranger, "0x", {"from": owner} - ) + evm_script_factories_registry.addEVMScriptFactory(stranger, "0x", {"from": owner}) -def test_add_evm_script_factory_invalid_length( - owner, stranger, evm_script_factories_registry -): +def test_add_evm_script_factory_invalid_length(owner, stranger, evm_script_factories_registry): "Must revert with message 'INVALID_PERMISSIONS' if called with permissions which have incorrect length" with reverts("INVALID_PERMISSIONS"): - evm_script_factories_registry.addEVMScriptFactory( - stranger, "0x0011223344", {"from": owner} - ) + evm_script_factories_registry.addEVMScriptFactory(stranger, "0x0011223344", {"from": owner}) def test_add_evm_script(owner, stranger, evm_script_factories_registry): "Must add new EVMScript factory and emit EVMScriptFactoryAdded(_evmScriptFactory, _permissions) event" permissions = stranger.address + "ffccddee" - tx = evm_script_factories_registry.addEVMScriptFactory( - stranger, permissions, {"from": owner} - ) + tx = evm_script_factories_registry.addEVMScriptFactory(stranger, permissions, {"from": owner}) assert tx.events["EVMScriptFactoryAdded"]["_evmScriptFactory"] == stranger assert tx.events["EVMScriptFactoryAdded"]["_permissions"] == permissions @@ -60,34 +48,24 @@ def test_add_evm_script_twice(owner, stranger, evm_script_factories_registry): "Must revert with message 'EVM_SCRIPT_FACTORY_ALREADY_ADDED'" "if called with already listed EVMScript factory address" permissions = stranger.address + "ffccddee" - evm_script_factories_registry.addEVMScriptFactory( - stranger, permissions, {"from": owner} - ) + evm_script_factories_registry.addEVMScriptFactory(stranger, permissions, {"from": owner}) with reverts("EVM_SCRIPT_FACTORY_ALREADY_ADDED"): - evm_script_factories_registry.addEVMScriptFactory( - stranger, permissions, {"from": owner} - ) + evm_script_factories_registry.addEVMScriptFactory(stranger, permissions, {"from": owner}) -def test_remove_evm_script_factory_not_found( - owner, stranger, evm_script_factories_registry -): +def test_remove_evm_script_factory_not_found(owner, stranger, evm_script_factories_registry): "Must revert with message 'EVM_SCRIPT_FACTORY_NOT_FOUND'" with reverts("EVM_SCRIPT_FACTORY_NOT_FOUND"): evm_script_factories_registry.removeEVMScriptFactory(stranger, {"from": owner}) -def test_remove_evm_script_factory( - owner, stranger, evm_script_factories_registry, extra_evm_script_factories -): +def test_remove_evm_script_factory(owner, stranger, evm_script_factories_registry, extra_evm_script_factories): "Must remove EVMScript factory from the list of allowed EVMScript factories" "and emit EVMScriptFactoryRemoved(_evmScriptFactory) event" # add many evm script factories permissions = stranger.address + "ffccddee" for evm_script_factory in extra_evm_script_factories: - evm_script_factories_registry.addEVMScriptFactory( - evm_script_factory, permissions, {"from": owner} - ) + evm_script_factories_registry.addEVMScriptFactory(evm_script_factory, permissions, {"from": owner}) # make a copy to avoid modifying the fixture object when popping evm_script_factories = extra_evm_script_factories.copy() @@ -105,30 +83,17 @@ def test_remove_evm_script_factory( for index in removing_order: evm_script_factory_to_remove = evm_script_factories.pop(index) - assert evm_script_factories_registry.isEVMScriptFactory( - evm_script_factory_to_remove - ) - tx = evm_script_factories_registry.removeEVMScriptFactory( - evm_script_factory_to_remove, {"from": owner} - ) - assert not evm_script_factories_registry.isEVMScriptFactory( - evm_script_factory_to_remove - ) + assert evm_script_factories_registry.isEVMScriptFactory(evm_script_factory_to_remove) + tx = evm_script_factories_registry.removeEVMScriptFactory(evm_script_factory_to_remove, {"from": owner}) + assert not evm_script_factories_registry.isEVMScriptFactory(evm_script_factory_to_remove) # validate events assert len(tx.events) == 1 - assert ( - tx.events["EVMScriptFactoryRemoved"]["_evmScriptFactory"] - == evm_script_factory_to_remove - ) + assert tx.events["EVMScriptFactoryRemoved"]["_evmScriptFactory"] == evm_script_factory_to_remove # validate that was deleted correct address by join # test set with resulting set their size must be same - evm_script_factories_after_remove = ( - evm_script_factories_registry.getEVMScriptFactories() - ) + evm_script_factories_after_remove = evm_script_factories_registry.getEVMScriptFactories() assert len(evm_script_factories) == len(evm_script_factories_after_remove) - len(set(evm_script_factories).union(evm_script_factories_after_remove)) == len( - evm_script_factories - ) + len(set(evm_script_factories).union(evm_script_factories_after_remove)) == len(evm_script_factories) diff --git a/tests/test_motion_settings.py b/tests/test_motion_settings.py index c48d1881..01901d1c 100644 --- a/tests/test_motion_settings.py +++ b/tests/test_motion_settings.py @@ -1,5 +1,5 @@ from brownie import reverts -from utils.test_helpers import access_controll_revert_message +from utils.test_helpers import access_revert_message import constants @@ -43,7 +43,7 @@ def test_set_motion_duration_called_with_permissions(owner, motion_settings): def test_set_motion_duration_called_without_permissions(stranger, motion_settings): "Must revert with correct Access Control message" "if called by address without 'DEFAULT_ADMIN_ROLE'" - with reverts(access_controll_revert_message(stranger)): + with reverts(access_revert_message(stranger)): motion_settings.setMotionDuration(0, {"from": stranger}) @@ -58,25 +58,18 @@ def test_set_objections_threshold_called_with_permissions(owner, motion_settings "Must update objections threshold when value is less or equal" "than MAX_OBJECTIONS_THRESHOLD and emits ObjectionsThresholdChanged(_newThreshold) event" new_objections_threshold = 2 * constants.DEFAULT_OBJECTIONS_THRESHOLD - assert ( - motion_settings.objectionsThreshold() == constants.DEFAULT_OBJECTIONS_THRESHOLD - ) - tx = motion_settings.setObjectionsThreshold( - new_objections_threshold, {"from": owner} - ) + assert motion_settings.objectionsThreshold() == constants.DEFAULT_OBJECTIONS_THRESHOLD + tx = motion_settings.setObjectionsThreshold(new_objections_threshold, {"from": owner}) assert motion_settings.objectionsThreshold() == new_objections_threshold assert len(tx.events) == 1 - assert ( - tx.events["ObjectionsThresholdChanged"]["_newThreshold"] - == new_objections_threshold - ) + assert tx.events["ObjectionsThresholdChanged"]["_newThreshold"] == new_objections_threshold def test_set_objections_threshold_without_permissions(stranger, motion_settings): "Must revert with correct Access Control message" "if called by address without 'DEFAULT_ADMIN_ROLE'" - with reverts(access_controll_revert_message(stranger)): + with reverts(access_revert_message(stranger)): motion_settings.setObjectionsThreshold(0, {"from": stranger}) @@ -85,9 +78,7 @@ def test_set_objections_threshold_called_with_too_large_value(owner, motion_sett "threshold is greater than MAX_OBJECTIONS_THRESHOLD" new_objections_threshold = 2 * motion_settings.MAX_OBJECTIONS_THRESHOLD() with reverts("VALUE_TOO_LARGE"): - motion_settings.setObjectionsThreshold( - new_objections_threshold, {"from": owner} - ) + motion_settings.setObjectionsThreshold(new_objections_threshold, {"from": owner}) def test_set_motions_limit_called_with_permissions(owner, motion_settings): @@ -101,16 +92,13 @@ def test_set_motions_limit_called_with_permissions(owner, motion_settings): assert motion_settings.motionsCountLimit() == new_motions_limit assert len(tx.events) == 1 - assert ( - tx.events["MotionsCountLimitChanged"]["_newMotionsCountLimit"] - == new_motions_limit - ) + assert tx.events["MotionsCountLimitChanged"]["_newMotionsCountLimit"] == new_motions_limit def test_set_motions_limit_called_without_permissions(stranger, motion_settings): "Must revert with correct Access Control message" "if called by address without 'DEFAULT_ADMIN_ROLE'" - with reverts(access_controll_revert_message(stranger)): + with reverts(access_revert_message(stranger)): motion_settings.setMotionsCountLimit(0, {"from": stranger}) diff --git a/tests/test_reward_programs.py b/tests/test_reward_programs.py index d8de2df3..20ff5e3a 100644 --- a/tests/test_reward_programs.py +++ b/tests/test_reward_programs.py @@ -1,28 +1,17 @@ -import pytest +import brownie import constants from brownie.network import chain -from brownie import ( - EasyTrack, - EVMScriptExecutor, - accounts -) +from brownie import EasyTrack, EVMScriptExecutor, accounts -from eth_abi import encode_single -from utils.evm_script import encode_call_script +from utils.evm_script import encode_calldata, encode_call_script +from utils import lido -from utils.config import ( - network_name -) - -from utils.lido import create_voting, execute_voting - -def encode_calldata(signature, values): - return "0x" + encode_single(signature, values).hex() def create_permission(contract, method): return contract.address + getattr(contract, method).signature[2:] + def test_reward_programs_easy_track( stranger, agent, @@ -77,43 +66,24 @@ def test_reward_programs_easy_track( ) # add TopUpRewardPrograms EVM script factory to easy track - new_immediate_payment_permission = create_permission( - finance, - "newImmediatePayment" - ) + new_immediate_payment_permission = create_permission(finance, "newImmediatePayment") - easy_track.addEVMScriptFactory( - top_up_reward_programs, new_immediate_payment_permission, {"from": deployer} - ) + easy_track.addEVMScriptFactory(top_up_reward_programs, new_immediate_payment_permission, {"from": deployer}) # deploy AddRewardProgram EVM script factory - add_reward_program = deployer.deploy( - AddRewardProgram, trusted_address, reward_programs_registry - ) + add_reward_program = deployer.deploy(AddRewardProgram, trusted_address, reward_programs_registry) # add AddRewardProgram EVM script factory to easy track - add_reward_program_permission = create_permission( - reward_programs_registry, - "addRewardProgram" - ) + add_reward_program_permission = create_permission(reward_programs_registry, "addRewardProgram") - easy_track.addEVMScriptFactory( - add_reward_program, add_reward_program_permission, {"from": deployer} - ) + easy_track.addEVMScriptFactory(add_reward_program, add_reward_program_permission, {"from": deployer}) # deploy RemoveRewardProgram EVM script factory - remove_reward_program = deployer.deploy( - RemoveRewardProgram, trusted_address, reward_programs_registry - ) + remove_reward_program = deployer.deploy(RemoveRewardProgram, trusted_address, reward_programs_registry) # add RemoveRewardProgram EVM script factory to easy track - remove_reward_program_permission = create_permission( - reward_programs_registry, - "removeRewardProgram" - ) - easy_track.addEVMScriptFactory( - remove_reward_program, remove_reward_program_permission, {"from": deployer} - ) + remove_reward_program_permission = create_permission(reward_programs_registry, "removeRewardProgram") + easy_track.addEVMScriptFactory(remove_reward_program, remove_reward_program_permission, {"from": deployer}) # transfer admin role to voting easy_track.grantRole(easy_track.DEFAULT_ADMIN_ROLE(), voting, {"from": deployer}) @@ -121,11 +91,10 @@ def test_reward_programs_easy_track( easy_track.revokeRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer, {"from": deployer}) assert not easy_track.hasRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer) - # create voting to grant permissions to EVM script executor to create new payments - - netname = "goerli" if network_name().split('-')[0] == "goerli" else "mainnet" + lido_contracts = lido.contracts(network=brownie.network.show_active()) - add_create_payments_permissions_voting_id, _ = create_voting( + # create voting to grant permissions to EVM script executor to create new payments + add_create_payments_permissions_voting_id, _ = lido_contracts.create_voting( evm_script=encode_call_script( [ ( @@ -139,30 +108,15 @@ def test_reward_programs_easy_track( ] ), description="Grant permissions to EVMScriptExecutor to make payments", - network=netname, tx_params={"from": agent}, ) # execute voting to add permissions to EVM script executor to create payments - execute_voting(add_create_payments_permissions_voting_id, netname) + lido_contracts.execute_voting(add_create_payments_permissions_voting_id) - add_reward_program_calldata = encode_calldata( - "(address,string)", [ - reward_program.address, - reward_program_title - ] - ) - # create new motion to add a reward program - expected_evm_script = add_reward_program.createEVMScript( - trusted_address, - add_reward_program_calldata - ) + add_reward_program_calldata = encode_calldata(["address", "string"], [reward_program.address, reward_program_title]) - tx = easy_track.createMotion( - add_reward_program, - add_reward_program_calldata, - {"from": trusted_address} - ) + tx = easy_track.createMotion(add_reward_program, add_reward_program_calldata, {"from": trusted_address}) motions = easy_track.getMotions() assert len(motions) == 1 @@ -183,7 +137,7 @@ def test_reward_programs_easy_track( # create new motion to top up reward program tx = easy_track.createMotion( top_up_reward_programs, - encode_single("(address[],uint256[])", [[reward_program.address], [int(5e18)]]), + encode_calldata(["address[]", "uint256[]"], [[reward_program.address], [int(5e18)]]), {"from": trusted_address}, ) motions = easy_track.getMotions() @@ -205,7 +159,7 @@ def test_reward_programs_easy_track( # create new motion to remove a reward program tx = easy_track.createMotion( remove_reward_program, - encode_single("(address)", [reward_program.address]), + encode_calldata(["address"], [reward_program.address]), {"from": trusted_address}, ) diff --git a/tests/test_reward_programs_registry.py b/tests/test_reward_programs_registry.py index 0086db92..e68de4b2 100644 --- a/tests/test_reward_programs_registry.py +++ b/tests/test_reward_programs_registry.py @@ -1,5 +1,5 @@ from brownie import reverts -from utils.test_helpers import access_controll_revert_message +from utils.test_helpers import access_revert_message def test_deploy(owner, voting, evm_script_executor_stub, RewardProgramsRegistry): @@ -18,30 +18,18 @@ def test_deploy(owner, voting, evm_script_executor_stub, RewardProgramsRegistry) assert contract.hasRole(contract.REMOVE_REWARD_PROGRAM_ROLE(), voting) # EVMScriptExecutor must have rights to add/remove reward programs - assert contract.hasRole( - contract.ADD_REWARD_PROGRAM_ROLE(), evm_script_executor_stub - ) - assert contract.hasRole( - contract.REMOVE_REWARD_PROGRAM_ROLE(), evm_script_executor_stub - ) + assert contract.hasRole(contract.ADD_REWARD_PROGRAM_ROLE(), evm_script_executor_stub) + assert contract.hasRole(contract.REMOVE_REWARD_PROGRAM_ROLE(), evm_script_executor_stub) def test_add_reward_program_called_by_stranger(stranger, reward_programs_registry): "Must revert with correct Access Control message if called by address without role 'ADD_REWARD_PROGRAM_ROLE'" - assert not reward_programs_registry.hasRole( - reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), stranger - ) - with reverts( - access_controll_revert_message( - stranger, reward_programs_registry.ADD_REWARD_PROGRAM_ROLE() - ) - ): + assert not reward_programs_registry.hasRole(reward_programs_registry.ADD_REWARD_PROGRAM_ROLE(), stranger) + with reverts(access_revert_message(stranger, reward_programs_registry.ADD_REWARD_PROGRAM_ROLE())): reward_programs_registry.addRewardProgram(stranger, "", {"from": stranger}) -def test_add_reward_program( - evm_script_executor_stub, stranger, reward_programs_registry -): +def test_add_reward_program(evm_script_executor_stub, stranger, reward_programs_registry): "Must add new reward program to rewardPrograms array and emit RewardProgramAdded(_rewardProgram, _title) event." "When called with already added reward program fails with error 'REWARD_PROGRAM_ALREADY_ADDED' error" new_reward_program = stranger @@ -65,18 +53,10 @@ def test_add_reward_program( ) -def test_remove_reward_program_called_by_stranger( - owner, stranger, reward_programs_registry -): +def test_remove_reward_program_called_by_stranger(owner, stranger, reward_programs_registry): "Must revert with correct Access Control message if called by address without role 'REMOVE_REWARD_PROGRAM_ROLE'" - assert not reward_programs_registry.hasRole( - reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), stranger - ) - with reverts( - access_controll_revert_message( - stranger, reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE() - ) - ): + assert not reward_programs_registry.hasRole(reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE(), stranger) + with reverts(access_revert_message(stranger, reward_programs_registry.REMOVE_REWARD_PROGRAM_ROLE())): reward_programs_registry.removeRewardProgram(stranger, {"from": stranger}) @@ -85,21 +65,15 @@ def test_remove_reward_program_with_not_existed_reward_program( ): "Must revert with message 'REWARD_PROGRAM_NOT_FOUND' error" with reverts("REWARD_PROGRAM_NOT_FOUND"): - reward_programs_registry.removeRewardProgram( - stranger, {"from": evm_script_executor_stub} - ) + reward_programs_registry.removeRewardProgram(stranger, {"from": evm_script_executor_stub}) -def test_remove_reward_program( - accounts, reward_programs_registry, evm_script_executor_stub -): +def test_remove_reward_program(accounts, reward_programs_registry, evm_script_executor_stub): "Must remove reward program from the list of allowed programs and emit RewardProgramRemoved(_rewardProgram) event" reward_programs = accounts[4:9] for reward_program in reward_programs: - reward_programs_registry.addRewardProgram( - reward_program, "", {"from": evm_script_executor_stub} - ) + reward_programs_registry.addRewardProgram(reward_program, "", {"from": evm_script_executor_stub}) # sets the order in which reward_programs will be removed removing_order = [2, 3, 1, 0, 0] @@ -109,9 +83,7 @@ def test_remove_reward_program( reward_program = reward_programs.pop(index) assert reward_programs_registry.isRewardProgram(reward_program) - tx = reward_programs_registry.removeRewardProgram( - reward_program, {"from": evm_script_executor_stub} - ) + tx = reward_programs_registry.removeRewardProgram(reward_program, {"from": evm_script_executor_stub}) # validate events assert len(tx.events) == 1 assert tx.events["RewardProgramRemoved"]["_rewardProgram"] == reward_program @@ -121,6 +93,4 @@ def test_remove_reward_program( assert len(reward_programs) == len(contract_reward_programs) # validate that was deleted correct address by join # test set with resulting set their size must be same - assert len(set(reward_programs).union(contract_reward_programs)) == len( - contract_reward_programs - ) + assert len(set(reward_programs).union(contract_reward_programs)) == len(contract_reward_programs) diff --git a/tests/test_vote_for_reward_programs.py b/tests/test_vote_for_reward_programs.py index c733f595..d6a3794e 100644 --- a/tests/test_vote_for_reward_programs.py +++ b/tests/test_vote_for_reward_programs.py @@ -1,46 +1,46 @@ +import pytest + from scripts.vote_for_reward_programs import start_vote -from utils import ( - lido, - deployed_easy_track -) +from utils import lido, deployed_easy_track -from utils.config import ( - network_name, - get_deployer_account, - get_is_live -) +from utils.config import get_network_name, get_deployer_account, get_is_live factories_to_remove_with_vote = [ # Intentionally left empty ] factories_to_add_with_vote = [ - '0x929547490Ceb6AeEdD7d72F1Ab8957c0210b6E51', - '0xE9eb838fb3A288bF59E9275Ccd7e124fDff88a9C', - '0x54058ee0E0c87Ad813C002262cD75B98A7F59218' + "0x929547490Ceb6AeEdD7d72F1Ab8957c0210b6E51", + "0xE9eb838fb3A288bF59E9275Ccd7e124fDff88a9C", + "0x54058ee0E0c87Ad813C002262cD75B98A7F59218", ] ldo_vote_executors_for_tests = { - 'mainnet': [ - '0x3e40d73eb977dc6a537af587d48316fee66e9c8c', - '0xb8d83908aab38a159f3da47a59d84db8e1838712', - '0xa2dfc431297aee387c05beef507e5335e684fbcd' + "mainnet": [ + "0x3e40d73eb977dc6a537af587d48316fee66e9c8c", + "0xb8d83908aab38a159f3da47a59d84db8e1838712", + "0xa2dfc431297aee387c05beef507e5335e684fbcd", + ], + "goerli": [ + "0xa5f1d7d49f581136cf6e58b32cbe9a2039c48ba1", + "0x4333218072d5d7008546737786663c38b4d561a4", + "0xfda7e01b2718c511bf016030010572e833c7ae6a", + ], + "holesky": [ + "0xaa6bfBCD634EE744CB8FE522b29ADD23124593D3", + "0xba59a84c6440e8cccfdb5448877e26f1a431fc8b", + "0x1d835790d93a28fb30d998c0cb27426e5d2d7c8c", ], - 'goerli': [ - '0xa5f1d7d49f581136cf6e58b32cbe9a2039c48ba1', - '0x4333218072d5d7008546737786663c38b4d561a4', - '0xfda7e01b2718c511bf016030010572e833c7ae6a' - ] } -def test_vote_for_reward_programs( - helpers, accounts, vote_id_from_env -): - netname = "goerli" if network_name().split('-')[0] == "goerli" else "mainnet" - contracts = lido.contracts(network=netname) - et_contracts = deployed_easy_track.contracts(network=netname) +@pytest.mark.skip(reason="already deployed om mainnet") +def test_vote_for_reward_programs(helpers, accounts, vote_id_from_env): + network_name = get_network_name() + + contracts = lido.contracts(network=network_name) + et_contracts = deployed_easy_track.contracts(network=network_name) easy_track = et_contracts.easy_track factories_before = easy_track.getEVMScriptFactories() @@ -54,14 +54,14 @@ def test_vote_for_reward_programs( ## ## START VOTE ## - deployer = get_deployer_account(get_is_live(), network=netname) - vote_id = vote_id_from_env or start_vote(netname, deployer) + deployer = get_deployer_account(get_is_live(), network=network_name) + vote_id = vote_id_from_env or start_vote(network_name, deployer) _ = helpers.execute_vote( vote_id=vote_id, accounts=accounts, dao_voting=contracts.aragon.voting, - ldo_vote_executors_for_tests=ldo_vote_executors_for_tests[netname] + ldo_vote_executors_for_tests=ldo_vote_executors_for_tests[network_name], ) factories_after = easy_track.getEVMScriptFactories() @@ -72,5 +72,6 @@ def test_vote_for_reward_programs( for f in factories_to_add_with_vote: assert f in factories_after - assert len(factories_after) - len(factories_before) \ - == len(factories_to_add_with_vote) - len(factories_to_remove_with_vote) + assert len(factories_after) - len(factories_before) == len(factories_to_add_with_vote) - len( + factories_to_remove_with_vote + ) diff --git a/utils/allowed_recipients_motions.py b/utils/allowed_recipients_motions.py new file mode 100644 index 00000000..288150c5 --- /dev/null +++ b/utils/allowed_recipients_motions.py @@ -0,0 +1,122 @@ +import brownie +from brownie.network import chain +from brownie import interface +from typing import List + +from eth_abi import encode +from utils.evm_script import encode_call_script, encode_calldata + +from utils import lido +import constants + + +MAX_SECONDS_IN_MONTH = 31 * 24 * 60 * 60 + + +def add_recipient_by_motion(recipient, recipient_title, easy_track, add_recipient_factory): + tx = easy_track.createMotion( + add_recipient_factory, + encode_calldata(["address", "string"], [recipient.address, recipient_title]), + {"from": add_recipient_factory.trustedCaller()}, + ) + + chain.sleep(constants.MIN_MOTION_DURATION + 100) + + easy_track.enactMotion( + tx.events["MotionCreated"]["_motionId"], + tx.events["MotionCreated"]["_evmScriptCallData"], + {"from": recipient}, + ) + + +def remove_recipient_by_motion(recipient, easy_track, remove_recipient_factory, allowed_recipients_registry): + call_data = encode(["address"], [recipient.address]) + + tx = easy_track.createMotion( + remove_recipient_factory, + call_data, + {"from": remove_recipient_factory.trustedCaller()}, + ) + + chain.sleep(constants.MIN_MOTION_DURATION + 100) + + easy_track.enactMotion( + tx.events["MotionCreated"]["_motionId"], + call_data, + {"from": recipient}, + ) + assert not allowed_recipients_registry.isRecipientAllowed(recipient) + + +def set_limit_parameters_by_aragon_voting(period_limit: int, period_duration: int, allowed_recipients_registry, agent): + """Do Aragon voting to set limit parameters to the allowed recipients registry""" + lido_contracts = lido.contracts(network=brownie.network.show_active()) + set_limit_parameters_voting_id, _ = lido_contracts.create_voting( + evm_script=encode_call_script( + [ + ( + allowed_recipients_registry.address, + allowed_recipients_registry.setLimitParameters.encode_input( + period_limit, + period_duration, + ), + ), + ] + ), + description="Set limit parameters", + tx_params={"from": agent}, + ) + + # execute voting to add permissions to EVM script executor to create payments + lido_contracts.execute_voting(set_limit_parameters_voting_id) + + assert allowed_recipients_registry.getLimitParameters() == ( + period_limit, + period_duration, + ) + + +def create_top_up_motion(recipients: List[str], amounts: List[int], easy_track, top_up_factory): + script_call_data = encode(["address[]", "uint256[]"], [recipients, amounts]) + tx = easy_track.createMotion( + top_up_factory, + script_call_data, + {"from": top_up_factory.trustedCaller()}, + ) + motion_id = tx.events["MotionCreated"]["_motionId"] + return motion_id, script_call_data + + +def do_payout_to_allowed_recipients_by_motion(recipients, amounts, easy_track, top_up_factory): + motion_id, script_call_data = create_top_up_motion(recipients, amounts, easy_track, top_up_factory) + + chain.sleep(constants.MIN_MOTION_DURATION + 100) + + easy_track.enactMotion( + motion_id, + script_call_data, + {"from": recipients[0]}, + ) + + +def get_balances(recipients, token): + return [interface.ERC20(token).balanceOf(r) for r in recipients] + + +def check_top_up(tx, balances_before, recipients, payouts, registry, top_up_factory): + limit, duration = registry.getLimitParameters() + spending = sum(payouts) + spendable = limit - spending + + assert registry.isUnderSpendableBalance(spendable, 0) + assert registry.isUnderSpendableBalance(limit, duration * MAX_SECONDS_IN_MONTH) + assert registry.getPeriodState()["_alreadySpentAmount"] == spending + assert registry.getPeriodState()["_spendableBalanceInPeriod"] == spendable + + balances = get_balances(recipients, top_up_factory.token()) + for before, now, payment in zip(balances_before, balances, payouts): + assert now == before + payment + + assert "SpendableAmountChanged" in tx.events + assert tx.events["SpendableAmountChanged"]["_alreadySpentAmount"] == spending + assert tx.events["SpendableAmountChanged"]["_spendableBalance"] == spendable diff --git a/utils/config.py b/utils/config.py index 22dc7e9a..e9edefa0 100644 --- a/utils/config.py +++ b/utils/config.py @@ -4,24 +4,21 @@ from utils import lido from typing import Optional -def network_name() -> Optional[str]: - if network.show_active() != None: - return network.show_active() - cli_args = sys.argv[1:] - net_ind = next((cli_args.index(arg) for arg in cli_args if arg == '--network'), len(cli_args)) - net_name = None - if net_ind != len(cli_args): - net_name = cli_args[net_ind+1] - return net_name + +def get_network_name() -> Optional[str]: + full_network_name = network.show_active() + + if full_network_name is None: + cli_args = sys.argv[1:] + net_ind = next((cli_args.index(arg) for arg in cli_args if arg == "--network"), len(cli_args)) + if net_ind != len(cli_args): + full_network_name = cli_args[net_ind + 1] + + return full_network_name.split("-")[0] + def get_is_live(): - dev_networks = [ - "development", - "hardhat", - "hardhat-fork", - "mainnet-fork", - "goerli-fork" - ] + dev_networks = ["development", "hardhat", "hardhat-fork", "mainnet-fork", "goerli-fork", "holesky-fork"] return network.show_active() not in dev_networks @@ -29,12 +26,10 @@ def get_deployer_account(is_live, network="mainnet"): contracts = lido.contracts(network=network) if not is_live: deployer = accounts[0] - contracts.ldo.transfer(deployer, 10 ** 18, {"from": contracts.aragon.agent}) + contracts.ldo.transfer(deployer, 10**18, {"from": contracts.aragon.agent}) return deployer if "DEPLOYER" not in os.environ: - raise EnvironmentError( - "Please set DEPLOYER env variable to the deployer account name" - ) + raise EnvironmentError("Please set DEPLOYER env variable to the deployer account name") return accounts.load(os.environ["DEPLOYER"]) diff --git a/utils/deployed_date_time.py b/utils/deployed_date_time.py new file mode 100644 index 00000000..33b6cdf9 --- /dev/null +++ b/utils/deployed_date_time.py @@ -0,0 +1,8 @@ +def date_time_contract(network: str = "mainnet") -> str: + if network == "mainnet" or network == "mainnet-fork": + return "0x75100bd564415731b5936a4a94d0dc29dde5db3c" + if network == "goerli" or network == "goerli-fork": + return "0xb1e4de1092D0D32613e4BbFBf4D68650862f43A6" + if network == "holesky" or network == "holesky-fork": + return "0xd6237FecDF9C1D9b023A5205C17549E3037EeEec" + raise NameError(f"""Unknown network "{network}". Supported networks: mainnet, goerli, holesky.""") diff --git a/utils/deployed_easy_track.py b/utils/deployed_easy_track.py index 34552dd4..3241e367 100644 --- a/utils/deployed_easy_track.py +++ b/utils/deployed_easy_track.py @@ -8,11 +8,12 @@ RewardProgramsRegistry, IncreaseNodeOperatorStakingLimit, TopUpLegoProgram, - Contract + Contract, ) + def addresses(network="mainnet"): - if network == "mainnet": + if network == "mainnet" or network == "mainnet-fork": return EasyTrackSetup( easy_track="0xF0211b7660680B49De1A7E9f25C65660F0a13Fea", evm_script_executor="0xFE5986E06210aC1eCC1aDCafc0cc7f8D63B3F977", @@ -22,42 +23,56 @@ def addresses(network="mainnet"): add_reward_program="0x9D15032b91d01d5c1D940eb919461426AB0dD4e3", remove_reward_program="0xc21e5e72Ffc223f02fC410aAedE3084a63963932", top_up_reward_programs="0x77781A93C4824d2299a38AC8bBB11eb3cd6Bc3B7", - reward_programs_registry="0x3129c041b372ee93a5a8756dc4ec6f154d85bc9a" + reward_programs_registry="0x3129c041b372ee93a5a8756dc4ec6f154d85bc9a", ), referral_partners=RewardPrograms( add_reward_program="0x929547490Ceb6AeEdD7d72F1Ab8957c0210b6E51", remove_reward_program="0xE9eb838fb3A288bF59E9275Ccd7e124fDff88a9C", top_up_reward_programs="0x54058ee0E0c87Ad813C002262cD75B98A7F59218", - reward_programs_registry="0xfCaD241D9D2A2766979A2de208E8210eDf7b7D4F" - ) + reward_programs_registry="0xfCaD241D9D2A2766979A2de208E8210eDf7b7D4F", + ), + ) + if network == "holesky" or network == "holesky-fork": + return EasyTrackSetup( + easy_track="0x1763b9ED3586B08AE796c7787811a2E1bc16163a", + evm_script_executor="0x2819B65021E13CEEB9AC33E77DB32c7e64e7520D", + increase_node_operator_staking_limit=None, + top_up_lego_program=None, + reward_programs=RewardPrograms( + add_reward_program=None, + remove_reward_program=None, + top_up_reward_programs=None, + reward_programs_registry=None, + ), + referral_partners=RewardPrograms( + add_reward_program=None, + remove_reward_program=None, + top_up_reward_programs=None, + reward_programs_registry=None, + ), ) - if network == "goerli": + if network == "goerli" or network == "goerli-fork": return EasyTrackSetup( easy_track="0xAf072C8D368E4DD4A9d4fF6A76693887d6ae92Af", evm_script_executor="0x3c9aca237b838c59612d79198685e7f20c7fe783", increase_node_operator_staking_limit="0xE033673D83a8a60500BcE02aBd9007ffAB587714", - top_up_lego_program="0xb2bcf211F103d7F13789394DD475c2274e044C4C", reward_programs=RewardPrograms( add_reward_program="0x5560d40b00EA3a64E9431f97B3c79b04e0cdF6F2", remove_reward_program="0x31B68d81125E52fE1aDfe4076F8945D1014753b5", top_up_reward_programs="0x8180949ac41EF18e844ff8dafE604a195d86Aea9", - reward_programs_registry="0x28a08f61AE129d0d8BD4380Ae5647e7Add0527ca" + reward_programs_registry="0x28a08f61AE129d0d8BD4380Ae5647e7Add0527ca", ), referral_partners=RewardPrograms( add_reward_program="0xe54ca3e867C52a34d262E94606C7A9371AB820c9", remove_reward_program="0x2A0c343087c6cFB721fFa20608A6eD0473C71275", top_up_reward_programs="0xB1E898faC74c377bEF16712Ba1CD4738606c19Ee", - reward_programs_registry="0x4CB0c9987fd670069e4b24c653981E86b261A2ca" - ) + reward_programs_registry="0x4CB0c9987fd670069e4b24c653981E86b261A2ca", + ), ) - raise NameError( - f"""Unknown network "{network}". Supported networks: mainnet, goerli.""" - ) + raise NameError(f"""Unknown network "{network}". Supported networks: mainnet, goerli, holesky.""") -def contract_or_none( - contract: Contract, - addr: Optional[str] -) -> Optional[Contract]: + +def contract_or_none(contract: Contract, addr: Optional[str]) -> Optional[Contract]: if not addr: return None return contract.at(addr) @@ -70,50 +85,44 @@ def contracts(network="mainnet"): evm_script_executor=contract_or_none(EVMScriptExecutor, network_addresses.evm_script_executor), increase_node_operator_staking_limit=contract_or_none( IncreaseNodeOperatorStakingLimit, - network_addresses.increase_node_operator_staking_limit - ), - top_up_lego_program=contract_or_none( - TopUpLegoProgram, - network_addresses.top_up_lego_program + network_addresses.increase_node_operator_staking_limit, ), + top_up_lego_program=contract_or_none(TopUpLegoProgram, network_addresses.top_up_lego_program), reward_programs=RewardPrograms( - add_reward_program=contract_or_none( - AddRewardProgram, - network_addresses.reward_programs.add_reward_program - ), + add_reward_program=contract_or_none(AddRewardProgram, network_addresses.reward_programs.add_reward_program), remove_reward_program=contract_or_none( RemoveRewardProgram, - network_addresses.reward_programs.remove_reward_program + network_addresses.reward_programs.remove_reward_program, ), top_up_reward_programs=contract_or_none( TopUpRewardPrograms, - network_addresses.reward_programs.top_up_reward_programs + network_addresses.reward_programs.top_up_reward_programs, ), reward_programs_registry=contract_or_none( RewardProgramsRegistry, - network_addresses.reward_programs.reward_programs_registry - ) + network_addresses.reward_programs.reward_programs_registry, + ), ), referral_partners=RewardPrograms( add_reward_program=contract_or_none( - AddRewardProgram, - network_addresses.referral_partners.add_reward_program + AddRewardProgram, network_addresses.referral_partners.add_reward_program ), remove_reward_program=contract_or_none( RemoveRewardProgram, - network_addresses.referral_partners.remove_reward_program + network_addresses.referral_partners.remove_reward_program, ), top_up_reward_programs=contract_or_none( TopUpRewardPrograms, - network_addresses.referral_partners.top_up_reward_programs + network_addresses.referral_partners.top_up_reward_programs, ), reward_programs_registry=contract_or_none( RewardProgramsRegistry, - network_addresses.referral_partners.reward_programs_registry - ) - ) + network_addresses.referral_partners.reward_programs_registry, + ), + ), ) + class EasyTrackSetup: def __init__( self, @@ -122,7 +131,7 @@ def __init__( increase_node_operator_staking_limit, top_up_lego_program, reward_programs, - referral_partners + referral_partners, ): self.easy_track = easy_track self.evm_script_executor = evm_script_executor @@ -131,13 +140,14 @@ def __init__( self.reward_programs = reward_programs self.referral_partners = referral_partners + class RewardPrograms: def __init__( self, add_reward_program, remove_reward_program, top_up_reward_programs, - reward_programs_registry + reward_programs_registry, ): self.add_reward_program = add_reward_program self.remove_reward_program = remove_reward_program diff --git a/utils/deployment.py b/utils/deployment.py index 8e8b591d..71440efa 100644 --- a/utils/deployment.py +++ b/utils/deployment.py @@ -1,3 +1,4 @@ +from dataclasses import dataclass from brownie import ( EasyTrack, TopUpLegoProgram, @@ -6,10 +7,34 @@ RemoveRewardProgram, TopUpRewardPrograms, RewardProgramsRegistry, - IncreaseNodeOperatorStakingLimit + IncreaseNodeOperatorStakingLimit, + AddAllowedRecipient, + RemoveAllowedRecipient, + TopUpAllowedRecipients, + AllowedRecipientsRegistry, ) +@dataclass +class AllowedRecipientsDeployConfig: + token: str + limit: int + period: int + spent_amount: int + trusted_caller: str + + +@dataclass +class AllowedRecipientsSingleRecipientSetupDeployConfig(AllowedRecipientsDeployConfig): + title: str + + +@dataclass +class AllowedRecipientsFullSetupDeployConfig(AllowedRecipientsDeployConfig): + titles: [str] + recipients: [str] + + def deploy_easy_track( admin, governance_token, @@ -28,12 +53,8 @@ def deploy_easy_track( ) -def deploy_evm_script_executor( - aragon_voting, easy_track, aragon_calls_script, tx_params -): - evm_script_executor = EVMScriptExecutor.deploy( - aragon_calls_script, easy_track, tx_params - ) +def deploy_evm_script_executor(aragon_voting, easy_track, aragon_calls_script, tx_params): + evm_script_executor = EVMScriptExecutor.deploy(aragon_calls_script, easy_track, tx_params) evm_script_executor.transferOwnership(aragon_voting, tx_params) easy_track.setEVMScriptExecutor(evm_script_executor, tx_params) return evm_script_executor @@ -44,31 +65,34 @@ def deploy_reward_programs_registry(voting, evm_script_executor, tx_params): voting, [voting, evm_script_executor], [voting, evm_script_executor], tx_params ) + +def deploy_allowed_recipients_registry(voting, evm_script_executor, date_time_contract, tx_params): + return AllowedRecipientsRegistry.deploy( + voting, + [voting, evm_script_executor], + [voting, evm_script_executor], + [voting], + [evm_script_executor], + date_time_contract, + tx_params, + ) + + def deploy_increase_node_operator_staking_limit(node_operators_registry, tx_params): return IncreaseNodeOperatorStakingLimit.deploy(node_operators_registry, tx_params) -def deploy_top_up_lego_program( - finance, lego_program, lego_committee_multisig, tx_params -): - return TopUpLegoProgram.deploy( - lego_committee_multisig, finance, lego_program, tx_params - ) +def deploy_top_up_lego_program(finance, lego_program, lego_committee_multisig, tx_params): + return TopUpLegoProgram.deploy(lego_committee_multisig, finance, lego_program, tx_params) -def deploy_add_reward_program( - reward_programs_registry, reward_programs_multisig, tx_params -): - return AddRewardProgram.deploy( - reward_programs_multisig, reward_programs_registry, tx_params - ) +def deploy_add_reward_program(reward_programs_registry, reward_programs_multisig, tx_params): + return AddRewardProgram.deploy(reward_programs_multisig, reward_programs_registry, tx_params) + + +def deploy_remove_reward_program(reward_programs_registry, reward_programs_multisig, tx_params): + return RemoveRewardProgram.deploy(reward_programs_multisig, reward_programs_registry, tx_params) -def deploy_remove_reward_program( - reward_programs_registry, reward_programs_multisig, tx_params -): - return RemoveRewardProgram.deploy( - reward_programs_multisig, reward_programs_registry, tx_params - ) def deploy_top_up_reward_programs( finance, @@ -86,6 +110,32 @@ def deploy_top_up_reward_programs( ) +def deploy_add_allowed_recipient(allowed_recipients_registry, committee_multisig, tx_params): + return AddAllowedRecipient.deploy(committee_multisig, allowed_recipients_registry, tx_params) + + +def deploy_remove_allowed_recipient(allowed_recipients_registry, committee_multisig, tx_params): + return RemoveAllowedRecipient.deploy(committee_multisig, allowed_recipients_registry, tx_params) + + +def deploy_top_up_allowed_recipients( + finance, + governance_token, + allowed_recipients_registry, + committee_multisig, + easy_track, + tx_params, +): + return TopUpAllowedRecipients.deploy( + committee_multisig, + allowed_recipients_registry, + finance, + governance_token, + easy_track, + tx_params, + ) + + def grant_roles(easy_track, admin, pause_address, tx_params): easy_track.grantRole(easy_track.PAUSE_ROLE(), admin, tx_params) easy_track.grantRole(easy_track.UNPAUSE_ROLE(), admin, tx_params) @@ -106,9 +156,7 @@ def add_evm_script_factories( ): easy_track.addEVMScriptFactory( increase_node_operator_staking_limit, - create_permission( - lido_contracts.node_operators_registry, "setNodeOperatorStakingLimit" - ), + create_permission(lido_contracts.node_operators_registry, "setNodeOperatorStakingLimit"), tx_params, ) easy_track.addEVMScriptFactory( @@ -123,9 +171,10 @@ def add_evm_script_factories( top_up_reward_programs, reward_programs_registry, lido_contracts, - tx_params + tx_params, ) + def add_evm_script_reward_program_factories( easy_track, add_reward_program, @@ -133,7 +182,7 @@ def add_evm_script_reward_program_factories( top_up_reward_programs, reward_programs_registry, lido_contracts, - tx_params + tx_params, ): easy_track.addEVMScriptFactory( top_up_reward_programs, @@ -151,6 +200,38 @@ def add_evm_script_reward_program_factories( tx_params, ) + +def attach_evm_script_allowed_recipients_factories( + easy_track, + add_allowed_recipient, + remove_allowed_recipient, + top_up_allowed_recipients, + allowed_recipients_registry, + finance, + tx_params, +): + new_immediate_payment_permission = create_permission(finance, "newImmediatePayment") + + update_limit_permission = create_permission(allowed_recipients_registry, "updateSpentAmount") + permissions = new_immediate_payment_permission + update_limit_permission[2:] + + easy_track.addEVMScriptFactory( + top_up_allowed_recipients, + permissions, + tx_params, + ) + easy_track.addEVMScriptFactory( + add_allowed_recipient, + create_permission(allowed_recipients_registry, "addRecipient"), + tx_params, + ) + easy_track.addEVMScriptFactory( + remove_allowed_recipient, + create_permission(allowed_recipients_registry, "removeRecipient"), + tx_params, + ) + + def transfer_admin_role(deployer, easy_track, new_admin, tx_params): easy_track.grantRole(easy_track.DEFAULT_ADMIN_ROLE(), new_admin, tx_params) easy_track.revokeRole(easy_track.DEFAULT_ADMIN_ROLE(), deployer, tx_params) diff --git a/utils/evm_script.py b/utils/evm_script.py index 2980c572..354a94ba 100644 --- a/utils/evm_script.py +++ b/utils/evm_script.py @@ -16,8 +16,12 @@ def strip_byte_prefix(hexstr): def encode_call_script(actions, spec_id=1): result = create_executor_id(spec_id) for to, calldata in actions: - addr_bytes = Web3.toBytes(hexstr=HexAddress(to)).hex() + addr_bytes = Web3.to_bytes(hexstr=HexAddress(to)).hex() calldata_bytes = strip_byte_prefix(calldata) - length = eth_abi.encode_single("uint32", len(calldata_bytes) // 2).hex() + length = eth_abi.encode(["uint32"], [len(calldata_bytes) // 2]).hex() result += addr_bytes + length[56:] + calldata_bytes return result + + +def encode_calldata(signature, values): + return "0x" + eth_abi.encode(signature, values).hex() diff --git a/utils/lido.py b/utils/lido.py index d745e24d..5904455e 100644 --- a/utils/lido.py +++ b/utils/lido.py @@ -1,10 +1,12 @@ -from brownie import interface, chain, accounts -from utils.evm_script import encode_call_script +import brownie +from utils import evm_script as evm_script_utils +DEFAULT_NETWORK = "mainnet" -def addresses(network="mainnet"): - if network == "mainnet": - return LidoSetup( + +def addresses(network=DEFAULT_NETWORK): + if network == "mainnet" or network == "mainnet-fork": + return LidoAddressesSetup( aragon=AragonSetup( acl="0x9895F0F17cc1d1891b6f18ee0b483B6f221b37Bb", agent="0x3e40d73eb977dc6a537af587d48316fee66e9c8c", @@ -13,13 +15,34 @@ def addresses(network="mainnet"): gov_token="0x5a98fcbea516cf06857215779fd812ca3bef1b32", calls_script="0x5cEb19e1890f677c3676d5ecDF7c501eBA01A054", token_manager="0xf73a1260d222f447210581ddf212d915c09a3249", + kernel="0xb8FFC3Cd6e7Cf5a098A1c92F48009765B24088Dc", ), steth="0xae7ab96520de3a18e5e111b5eaab095312d7fe84", - oracle="0x442af784A788A5bd6F42A01Ebe9F287a871243fb", node_operators_registry="0x55032650b14df07b85bf18a3a3ec8e0af2e028d5", + simple_dvt="0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + staking_router="0xFdDf38947aFB03C621C71b06C9C70bce73f12999", + locator="0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb", + ) + if network == "holesky" or network == "holesky-fork": + return LidoAddressesSetup( + aragon=AragonSetup( + acl="0xfd1E42595CeC3E83239bf8dFc535250e7F48E0bC", + agent="0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d", + voting="0xdA7d2573Df555002503F29aA4003e398d28cc00f", + finance="0xf0F281E5d7FBc54EAFcE0dA225CDbde04173AB16", + gov_token="0x14ae7daeecdf57034f3E9db8564e46Dba8D97344", + calls_script="0xAa8B4F258a4817bfb0058b861447878168ddf7B0", + token_manager="0xFaa1692c6eea8eeF534e7819749aD93a1420379A", + kernel="0x3b03f75Ec541Ca11a223bB58621A3146246E1644", + ), + steth="0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034", + node_operators_registry="0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC", + simple_dvt="0x11a93807078f8BB880c1BD0ee4C387537de4b4b6", + staking_router="0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229", + locator="0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8", ) - if network == "goerli": - return LidoSetup( + if network == "goerli" or network == "goerli-fork": + return LidoAddressesSetup( aragon=AragonSetup( acl="0xb3cf58412a00282934d3c3e73f49347567516e98", agent="0x4333218072d5d7008546737786663c38b4d561a4", @@ -28,97 +51,116 @@ def addresses(network="mainnet"): gov_token="0x56340274fB5a72af1A3C6609061c451De7961Bd4", calls_script="0x1b4fb0c1357afd3f267c5e897ecfec75938c7436", token_manager="0xdfe76d11b365f5e0023343a367f0b311701b3bc1", + kernel="0x1dD91b354Ebd706aB3Ac7c727455C7BAA164945A", ), steth="0x1643e812ae58766192cf7d2cf9567df2c37e9b7f", - oracle="0x24d8451bc07e7af4ba94f69acdd9ad3c6579d9fb", node_operators_registry="0x9d4af1ee19dad8857db3a45b0374c81c8a1c6320", + simple_dvt=None, + staking_router="0xa3Dbd317E53D363176359E10948BA0b1c0A4c820", + locator="0x1eDf09b5023DC86737b59dE68a8130De878984f5", ) raise NameError( - f"""Unknown network "{network}". Supported networks: mainnet, goerli.""" + f"""Unknown network "{network}". Supported networks: mainnet, mainnet-fork goerli, goerli-fork, holesky, holesky-fork""" ) -def contracts(network="mainnet", interface=interface): - network_addresses = addresses(network) - return LidoSetup( - aragon=AragonSetup( - acl=interface.ACL(network_addresses.aragon.acl), - agent=interface.Agent(network_addresses.aragon.agent), - voting=interface.Voting(network_addresses.aragon.voting), - finance=interface.Finance(network_addresses.aragon.finance), - gov_token=interface.MiniMeToken(network_addresses.aragon.gov_token), - calls_script=interface.CallsScript(network_addresses.aragon.calls_script), - token_manager=interface.TokenManager( - network_addresses.aragon.token_manager - ), - ), - steth=interface.Lido(network_addresses.steth), - oracle=interface.Oracle(network_addresses.oracle), - node_operators_registry=interface.NodeOperatorsRegistry( - network_addresses.node_operators_registry - ), - ) +def contracts(network=DEFAULT_NETWORK): + return LidoContractsSetup(brownie.interface, lido_addresses=addresses(network)) -def permissions(contracts): - return Permissions(contracts) - +def allowed_recipients_builder(network=DEFAULT_NETWORK): + if network == "mainnet" or network == "mainnet-fork": + return brownie.AllowedRecipientsBuilder.at("0x958e0D946D014F377421a53AB5f9180d4485e63B") + if network == "holesky" or network == "holesky-fork": + return brownie.AllowedRecipientsBuilder.at("0xeC3785b13b21c226D66B5bC2E82BB2f4226f715e") + if network == "goerli" or network == "goerli-fork": + return brownie.AllowedRecipientsBuilder.at("0x1082512D1d60a0480445353eb55de451D261b684") + raise NameError( + f"""Unknown network "{network}". Supported networks: mainnet, mainnet-fork, holesky, holesky-fork, goerli, goerli-fork""" + ) -def create_voting(evm_script, description, network="mainnet", tx_params=None): - lido_contracts = contracts(network) - voting = lido_contracts.aragon.voting - voting_tx = lido_contracts.aragon.token_manager.forward( - encode_call_script( - [ - ( - voting.address, - voting.newVote.encode_input(evm_script, description), - ) - ] - ), - tx_params or {"from": lido_contracts.aragon.agent}, - ) - return voting_tx.events["StartVote"]["voteId"], voting_tx - - -def execute_voting(voting_id, network="mainnet"): - lido_contracts = contracts(network=network) - voting = lido_contracts.aragon.voting - if voting.getVote(voting_id)["executed"]: - return - ldo_holders = [ - "0x3e40d73eb977dc6a537af587d48316fee66e9c8c", - "0xb8d83908aab38a159f3da47a59d84db8e1838712", - "0xa2dfc431297aee387c05beef507e5335e684fbcd", - ] - for holder_addr in ldo_holders: - if not voting.canVote(voting_id, holder_addr): - print(f"{holder_addr} can't vote in voting {voting_id}") - continue - accounts[0].transfer(holder_addr, "0.1 ether") - account = accounts.at(holder_addr, force=True) - voting.vote(voting_id, True, False, {"from": account}) - - # voting.vote(voting_id, True, False, {"from": agent}) - chain.sleep(3 * 60 * 60 * 24) - chain.mine() - assert voting.canExecute(voting_id) - voting.executeVote(voting_id, {"from": accounts[0]}) - - -class LidoSetup: - def __init__(self, aragon, steth, oracle, node_operators_registry): +class LidoContractsSetup: + def __init__(self, interface, lido_addresses): + self.lido_addresses = lido_addresses + self.aragon = AragonSetup( + acl=interface.ACL(lido_addresses.aragon.acl), + agent=interface.Agent(lido_addresses.aragon.agent), + voting=interface.Voting(lido_addresses.aragon.voting), + finance=interface.Finance(lido_addresses.aragon.finance), + gov_token=interface.MiniMeToken(lido_addresses.aragon.gov_token), + calls_script=interface.CallsScript(lido_addresses.aragon.calls_script), + token_manager=interface.TokenManager(lido_addresses.aragon.token_manager), + kernel=interface.Kernel(lido_addresses.aragon.kernel), + ) + self.steth = interface.Lido(lido_addresses.steth) + self.node_operators_registry = interface.NodeOperatorsRegistry(lido_addresses.node_operators_registry) + self.simple_dvt = ( + None if not lido_addresses.simple_dvt else interface.NodeOperatorsRegistry(lido_addresses.simple_dvt) + ) + self.ldo = self.aragon.gov_token + self.permissions = Permissions(contracts=self) + self.staking_router = interface.StakingRouter(lido_addresses.staking_router) + self.locator = interface.LidoLocator(lido_addresses.locator) + + def create_voting(self, evm_script, description, tx_params=None): + voting = self.aragon.voting + + voting_tx = self.aragon.token_manager.forward( + evm_script_utils.encode_call_script( + [ + ( + voting.address, + voting.newVote.encode_input(evm_script, description), + ) + ] + ), + tx_params or {"from": self.aragon.agent}, + ) + return voting_tx.events["StartVote"]["voteId"], voting_tx + + def execute_voting(self, voting_id): + voting = self.aragon.voting + if voting.getVote(voting_id)["executed"]: + print(f"Voting {voting_id} already executed") + return + ldo_holders = [self.aragon.agent] + for holder_addr in ldo_holders: + if not voting.canVote(voting_id, holder_addr): + print(f"{holder_addr} can't vote in voting {voting_id}") + continue + brownie.accounts[0].transfer(holder_addr, "0.1 ether") + account = brownie.accounts.at(holder_addr, force=True) + voting.vote(voting_id, True, False, {"from": account}) + + brownie.chain.sleep(3 * 60 * 60 * 24) + brownie.chain.mine() + assert voting.canExecute(voting_id) + voting.executeVote(voting_id, {"from": brownie.accounts[0]}) + + +class LidoAddressesSetup: + def __init__(self, aragon, steth, node_operators_registry, simple_dvt, staking_router, locator): self.aragon = aragon self.steth = steth - self.oracle = oracle self.node_operators_registry = node_operators_registry + self.simple_dvt = simple_dvt self.ldo = self.aragon.gov_token + self.staking_router = staking_router + self.locator = locator class AragonSetup: def __init__( - self, acl, agent, voting, finance, gov_token, calls_script, token_manager + self, + acl, + agent, + voting, + finance, + gov_token, + calls_script, + token_manager, + kernel, ): self.acl = acl self.agent = agent @@ -127,6 +169,7 @@ def __init__( self.gov_token = gov_token self.calls_script = calls_script self.token_manager = token_manager + self.kernel = kernel class Permissions: @@ -135,10 +178,7 @@ def __init__(self, contracts): self.finance = FinancePermissions(contracts.aragon.finance) self.agent = AgentPermissions(contracts.aragon.agent) self.lido = LidoPermissions(contracts.steth) - self.node_operators_registry = NodeOperatorsRegistryPermissions( - contracts.node_operators_registry - ) - self.oracle = OraclePermissions(contracts.oracle) + self.node_operators_registry = NodeOperatorsRegistryPermissions(contracts.node_operators_registry) self.token_manager = TokenManagerPermissions(contracts.aragon.token_manager) self.voting = VotingPermissions(contracts.aragon.voting) @@ -155,7 +195,6 @@ def all(self): + list(self.agent.__dict__.values()) + list(self.lido.__dict__.values()) + list(self.node_operators_registry.__dict__.values()) - + list(self.oracle.__dict__.values()) + list(self.token_manager.__dict__.values()) + list(self.voting.__dict__.values()) ) @@ -172,15 +211,11 @@ def __init__(self, finance_app): class AgentPermissions: def __init__(self, agent_app): - self.ADD_PROTECTED_TOKEN_ROLE = Permission( - agent_app, "ADD_PROTECTED_TOKEN_ROLE" - ) + self.ADD_PROTECTED_TOKEN_ROLE = Permission(agent_app, "ADD_PROTECTED_TOKEN_ROLE") self.TRANSFER_ROLE = Permission(agent_app, "TRANSFER_ROLE") self.RUN_SCRIPT_ROLE = Permission(agent_app, "RUN_SCRIPT_ROLE") self.SAFE_EXECUTE_ROLE = Permission(agent_app, "SAFE_EXECUTE_ROLE") - self.REMOVE_PROTECTED_TOKEN_ROLE = Permission( - agent_app, "REMOVE_PROTECTED_TOKEN_ROLE" - ) + self.REMOVE_PROTECTED_TOKEN_ROLE = Permission(agent_app, "REMOVE_PROTECTED_TOKEN_ROLE") self.DESIGNATE_SIGNER_ROLE = Permission(agent_app, "DESIGNATE_SIGNER_ROLE") self.EXECUTE_ROLE = Permission(agent_app, "EXECUTE_ROLE") self.ADD_PRESIGNED_HASH_ROLE = Permission(agent_app, "ADD_PRESIGNED_HASH_ROLE") @@ -189,48 +224,17 @@ def __init__(self, agent_app): class LidoPermissions: def __init__(self, lido_app): self.PAUSE_ROLE = Permission(lido_app, "PAUSE_ROLE") - self.SET_ORACLE = Permission(lido_app, "SET_ORACLE") - self.MANAGE_WITHDRAWAL_KEY = Permission(lido_app, "MANAGE_WITHDRAWAL_KEY") - self.MANAGE_FEE = Permission(lido_app, "MANAGE_FEE") - self.SET_TREASURY = Permission(lido_app, "SET_TREASURY") - self.BURN_ROLE = Permission(lido_app, "BURN_ROLE") - self.SET_INSURANCE_FUND = Permission(lido_app, "SET_INSURANCE_FUND") + self.RESUME_ROLE = Permission(lido_app, "RESUME_ROLE") + self.STAKING_PAUSE_ROLE = Permission(lido_app, "STAKING_PAUSE_ROLE") + self.STAKING_CONTROL_ROLE = Permission(lido_app, "STAKING_CONTROL_ROLE") class NodeOperatorsRegistryPermissions: def __init__(self, node_operators_registry_app): - self.SET_NODE_OPERATOR_ADDRESS_ROLE = Permission( - node_operators_registry_app, "SET_NODE_OPERATOR_ADDRESS_ROLE" - ) - self.SET_NODE_OPERATOR_NAME_ROLE = Permission( - node_operators_registry_app, "SET_NODE_OPERATOR_NAME_ROLE" - ) - self.ADD_NODE_OPERATOR_ROLE = Permission( - node_operators_registry_app, "ADD_NODE_OPERATOR_ROLE" - ) - self.REPORT_STOPPED_VALIDATORS_ROLE = Permission( - node_operators_registry_app, "REPORT_STOPPED_VALIDATORS_ROLE" - ) - self.SET_NODE_OPERATOR_ACTIVE_ROLE = Permission( - node_operators_registry_app, "SET_NODE_OPERATOR_ACTIVE_ROLE" - ) - self.SET_NODE_OPERATOR_LIMIT_ROLE = Permission( - node_operators_registry_app, "SET_NODE_OPERATOR_LIMIT_ROLE" - ) - self.MANAGE_SIGNING_KEYS = Permission( - node_operators_registry_app, "MANAGE_SIGNING_KEYS" - ) - - -class OraclePermissions: - def __init__(self, oracle_app): - self.MANAGE_QUORUM = Permission(oracle_app, "MANAGE_QUORUM") - self.SET_BEACON_REPORT_RECEIVER = Permission( - oracle_app, "SET_BEACON_REPORT_RECEIVER" - ) - self.MANAGE_MEMBERS = Permission(oracle_app, "MANAGE_MEMBERS") - self.SET_BEACON_SPEC = Permission(oracle_app, "SET_BEACON_SPEC") - self.SET_REPORT_BOUNDARIES = Permission(oracle_app, "SET_REPORT_BOUNDARIES") + self.STAKING_ROUTER_ROLE = Permission(node_operators_registry_app, "STAKING_ROUTER_ROLE") + self.MANAGE_NODE_OPERATOR_ROLE = Permission(node_operators_registry_app, "MANAGE_NODE_OPERATOR_ROLE") + self.MANAGE_SIGNING_KEYS = Permission(node_operators_registry_app, "MANAGE_SIGNING_KEYS") + self.SET_NODE_OPERATOR_LIMIT_ROLE = Permission(node_operators_registry_app, "SET_NODE_OPERATOR_LIMIT_ROLE") class TokenManagerPermissions: @@ -239,9 +243,7 @@ def __init__(self, token_manager_app): self.ASSIGN_ROLE = Permission(token_manager_app, "ASSIGN_ROLE") self.BURN_ROLE = Permission(token_manager_app, "BURN_ROLE") self.MINT_ROLE = Permission(token_manager_app, "MINT_ROLE") - self.REVOKE_VESTINGS_ROLE = Permission( - token_manager_app, "REVOKE_VESTINGS_ROLE" - ) + self.REVOKE_VESTINGS_ROLE = Permission(token_manager_app, "REVOKE_VESTINGS_ROLE") class VotingPermissions: diff --git a/utils/log.py b/utils/log.py index cec2f647..9168deeb 100644 --- a/utils/log.py +++ b/utils/log.py @@ -5,6 +5,7 @@ color_gray = "\x1b[0;m" color_end = "\033[0m" + def highlight(text, color=color_hl): return f"{color}{text}{color_end}" @@ -17,9 +18,11 @@ def ok(text, value=None): print(result) + def br(): print(highlight("-" * 10, color_gray)) + def nb(text, value=None, color_hl=color_hl): result = highlight(">>>> ", color_yellow) + text diff --git a/utils/permission_parameters.py b/utils/permission_parameters.py new file mode 100644 index 00000000..3b58aeb7 --- /dev/null +++ b/utils/permission_parameters.py @@ -0,0 +1,125 @@ +""" Aragon ACL permission parameters + +This module contains classes and functions to create permission parameters for Aragon ACL. +It tries to recreate the original API for the sake of simplicity. +See https://hack.aragon.org/docs/aragonos-ref#parameter-interpretation for details + +NB! Constants MUST be equal to ones in deployed Lido ACL contract +https://etherscan.io/address/0x9f3b9198911054b122fdb865f8a5ac516201c339#code +""" + +from dataclasses import dataclass +from enum import Enum, IntEnum +from typing import Union, List +from brownie import convert + + +# enum Op { NONE, EQ, NEQ, GT, LT, GTE, LTE, RET, NOT, AND, OR, XOR, IF_ELSE } +class Op(Enum): + """Enum values depends on enum in ACL contract itself + See https://etherscan.io/address/0x9f3b9198911054b122fdb865f8a5ac516201c339#code#L802 to check + NB! It changes in future versions of the contract + """ + + NONE = 0 + EQ = 1 + NEQ = 2 + GT = 3 + LT = 4 + GTE = 5 + LTE = 6 + RET = 7 + NOT = 8 + AND = 9 + OR = 10 + XOR = 11 + IF_ELSE = 12 + + +class SpecialArgumentID(IntEnum): + """Special argument ids that enables different comparison modes""" + + BLOCK_NUMBER_PARAM_ID = 200 + TIMESTAMP_PARAM_ID = 201 # + ORACLE_PARAM_ID = 203 # auth call to IACLOracle + LOGIC_OP_PARAM_ID = 204 # logic operations + PARAM_VALUE_PARAM_ID = 205 # just a value to use with Op.RET + + +ArgumentID = Union[int, SpecialArgumentID] +"""Determines how the comparison value is fetched. From 0 to 200 it refers to the argument index number passed to the +role. After 200, there are some special Argument IDs: """ + + +class ArgumentValue(int): + """ + Argument Value (uint240): the value to compare against, depending on the argument. It is a regular Ethereum memory + word that loses its two most significant bytes of precision. The reason for this was to allow parameters to be saved + in just one storage slot, saving significant gas. Even though uint240s are used, it can be used to store any integer + up to 2^30 - 1, addresses, and bytes32. In the case of comparing hashes, losing 2 bytes of precision shouldn't be a + dealbreaker if the hash algorithm is secure. + """ + + def __new__(cls, value: Union[int, str]): + return super().__new__(cls, _to_uint240(value)) + + +@dataclass +class Param: + id: ArgumentID + op: Op + value: ArgumentValue + + def to_uint256(self) -> int: + id8 = convert.to_uint(self.id, "uint8") + op8 = convert.to_uint(self.op.value, "uint8") + value240 = convert.to_uint(self.value, "uint240") + return convert.to_uint((id8 << 248) + (op8 << 240) + value240, "uint256") + + def __str__(self): + value = hex(self.value) if self.op == Op.EQ else self.value + special_id = SpecialArgumentID(self.id).name if self.id > 200 else self.id + + value_clause = f"value={value})" + if self.op == Op.IF_ELSE: + if_param = value & 0xFFFFFFFF + then_param = (value & (0xFFFFFFFF << 32)) >> 32 + else_param = (value & (0xFFFFFFFF << 64)) >> 64 + value_clause = f"if={if_param} then={then_param} else={else_param}" + elif self.op == Op.AND or self.op == Op.OR or self.op == Op.NOT or self.op == Op.XOR: + left = value & 0xFFFFFFFF + right = (value & (0xFFFFFFFF << 32)) >> 32 + value_clause = f"left={left} right={right}" + return f"Param(ArgumentID={special_id}, op={self.op}, {value_clause})" + + +def encode_permission_params(params: List[Param]) -> List[int]: + return list(map(lambda p: p.to_uint256(), params)) + + +def encode_argument_value_op(left: int, right: int) -> ArgumentValue: + return encode_argument_value_if(left, right, 0) + + +def encode_argument_value_if(condition: int, success: int, failure: int) -> ArgumentValue: + condition32 = convert.to_uint(condition, "uint32") + success32 = convert.to_uint(success, "uint32") + failure32 = convert.to_uint(failure, "uint32") + + value = condition32 + (success32 << 32) + (failure32 << 64) + + return ArgumentValue(convert.to_uint(value, "uint240")) + + +def _to_uint240(val: Union[int, str]) -> int: + # Possibly, not explicit enough way to handle addresses + if isinstance(val, str) and (val[:2] == "0x"): + val = int(val, 16) + return ~(0xFFFF << 240) & val + + +def parse(val: int) -> Param: + arg_id = (val & (0xFF << 248)) >> 248 + op = (val & (0xFF << 240)) >> 240 + val = _to_uint240(val) + return Param(arg_id, Op(op), ArgumentValue(val)) diff --git a/utils/test_helpers.py b/utils/test_helpers.py index e80f02ad..d7021c48 100644 --- a/utils/test_helpers.py +++ b/utils/test_helpers.py @@ -1,15 +1,22 @@ +from datetime import datetime, timezone + +from brownie import chain + from utils import log CANCEL_ROLE = "0x9f959e00d95122f5cbd677010436cf273ef535b86b056afc172852144b9491d7" PAUSE_ROLE = "0x139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d" UNPAUSE_ROLE = "0x265b220c5a8891efdd9e1b1b7fa72f257bd5169f8d87e319cf3dad6ff52b94ae" -DEFAULT_ADMIN_ROLE = ( - "0x0000000000000000000000000000000000000000000000000000000000000000" -) +DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000" +SET_PARAMETERS_ROLE = "0x260b83d52a26066d8e9db550fa70395df5f3f064b50ff9d8a94267d9f1fe1967" +UPDATE_SPENT_AMOUNT_ROLE = "0xc5260260446719a726d11a6faece21d19daa48b4cbcca118345832d4cb71df99" +ADD_RECIPIENT_TO_ALLOWED_LIST_ROLE = "0xec20c52871c824e5437859e75ac830e83aaaaeb7b0ffd850de830ddd3e385276" +REMOVE_RECIPIENT_FROM_ALLOWED_LIST_ROLE = "0x491d7752c25cfca0f73715cde1130022a9b815373f91a996bbb1ba8943efc99b" PERMISSION_ERROR_TEMPLATE = "AccessControl: account %s is missing role %s" -def access_controll_revert_message(sender, role=DEFAULT_ADMIN_ROLE): +def access_revert_message(sender, role=DEFAULT_ADMIN_ROLE): + """Format access error message crafted by OpenZeppelin/AccessControl contract""" PERMISSION_ERROR_TEMPLATE = "AccessControl: account %s is missing role %s" return PERMISSION_ERROR_TEMPLATE % (sender.address.lower(), role) @@ -17,3 +24,178 @@ def access_controll_revert_message(sender, role=DEFAULT_ADMIN_ROLE): def assert_equals(desc, actual, expected): assert actual == expected log.ok(desc, actual) + + +def assert_single_event(receipt, event_name, args: dict): + assert ( + len(receipt.events) == 1 + ), f"event '{event_name}' must exist and be single (all events: {', '.join(receipt.events.keys())})" + assert dict(receipt.events[event_name]) == args, f"incorrect event '{event_name}' arguments" + + +def assert_event_exists(receipt, event_name, args: dict): + assert dict(receipt.events[event_name]) == args, f"incorrect event '{event_name}' arguments" + + +def get_month_start_timestamp(any_point_in_this_month: datetime): + return int( + any_point_in_this_month.replace( + day=1, hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc + ).timestamp() + ) + + +def get_date_in_next_period(any_point_in_this_month: datetime, period_duration_months: int): + NUM_MONTHS = 12 + next_month_unlimited_from_zero = any_point_in_this_month.month + (period_duration_months - 1) + next_month = 1 + (next_month_unlimited_from_zero % NUM_MONTHS) + next_year = any_point_in_this_month.year + if next_month_unlimited_from_zero >= NUM_MONTHS: + next_year += 1 + + next_day = min(any_point_in_this_month.day, 28) + + return any_point_in_this_month.replace(year=next_year, month=next_month, day=next_day) + + +def get_next_month_start_timestamp(any_point_in_this_month: datetime, num_months: int): + NUM_MONTHS = 12 + next_month_unlimited_from_zero = any_point_in_this_month.month + (num_months - 1) + next_month = 1 + (next_month_unlimited_from_zero % NUM_MONTHS) + next_year = any_point_in_this_month.year + if next_month_unlimited_from_zero >= NUM_MONTHS: + next_year += 1 + + return int( + any_point_in_this_month.replace( + year=next_year, + month=next_month, + day=1, + hour=0, + minute=0, + second=0, + microsecond=0, + tzinfo=timezone.utc, + ).timestamp() + ) + + +def calc_period_first_month(period_duration, current_month): + """Calculates the same value as LimitsChecker/_getFirstMonthInPeriodFromMonth""" + data = { + (1, 1): 1, + (1, 2): 2, + (1, 3): 3, + (1, 4): 4, + (1, 5): 5, + (1, 6): 6, + (1, 7): 7, + (1, 8): 8, + (1, 9): 9, + (1, 10): 10, + (1, 11): 11, + (1, 12): 12, + (2, 1): 1, + (2, 2): 1, + (2, 3): 3, + (2, 4): 3, + (2, 5): 5, + (2, 6): 5, + (2, 7): 7, + (2, 8): 7, + (2, 9): 9, + (2, 10): 9, + (2, 11): 11, + (2, 12): 11, + (3, 1): 1, + (3, 2): 1, + (3, 3): 1, + (3, 4): 4, + (3, 5): 4, + (3, 6): 4, + (3, 7): 7, + (3, 8): 7, + (3, 9): 7, + (3, 10): 10, + (3, 11): 10, + (3, 12): 10, + (6, 1): 1, + (6, 2): 1, + (6, 3): 1, + (6, 4): 1, + (6, 5): 1, + (6, 6): 1, + (6, 7): 7, + (6, 8): 7, + (6, 9): 7, + (6, 10): 7, + (6, 11): 7, + (6, 12): 7, + (12, 1): 1, + (12, 2): 1, + (12, 3): 1, + (12, 4): 1, + (12, 5): 1, + (12, 6): 1, + (12, 7): 1, + (12, 8): 1, + (12, 9): 1, + (12, 10): 1, + (12, 11): 1, + (12, 12): 1, + } + return data[(period_duration, current_month)] + + +def calc_period_range(period_duration: int, now_timestamp: int): + """Calculates the same range as LimitsChecker.sol""" + now = datetime.fromtimestamp(now_timestamp) + first_month = calc_period_first_month(period_duration, now.month) + first_month_date = now.replace(month=first_month) + next_period_date = get_date_in_next_period(first_month_date, period_duration) + + return ( + get_month_start_timestamp(first_month_date), + get_month_start_timestamp(next_period_date), + ) + + +def advance_chain_time_to_n_seconds_before_current_period_end(period_duration: int, seconds_before: int): + chain_now = chain.time() + _, first_second_of_next_period = calc_period_range(period_duration, chain_now) + seconds_till_period_end = first_second_of_next_period - 1 - chain_now + assert ( + seconds_till_period_end > seconds_before + ), f"cannot move chain time {seconds_before} seconds before current period \ + end, because there {seconds_till_period_end} seconds left till current period end" + + chain.sleep(seconds_till_period_end - seconds_before) + assert chain.time() + seconds_before + 1 >= first_second_of_next_period + + +def advance_chain_time_to_beginning_of_the_next_period(period_duration: int): + """Helps to avoid the situation when the tests run at the end of current period + and the period advanced unexpectedly while the test was run and/or chain time + advanced till the motion is ended. + Advances to the first or the second day of the month roughly, just to avoid + dealing with timezones""" + + chain_now = chain.time() + _, first_second_of_next_period = calc_period_range(period_duration, chain_now) + chain.sleep(first_second_of_next_period - chain_now) + assert chain.time() >= first_second_of_next_period + + +def advance_chain_time_to_middle_of_the_next_period(period_duration: int): + advance_chain_time_to_beginning_of_the_next_period(period_duration) + + chain_now = chain.time() + _, first_second_of_next_period = calc_period_range(period_duration, chain_now) + half_period_size_seconds_to_skip = int((first_second_of_next_period - chain_now) / 2) + chain.sleep(half_period_size_seconds_to_skip) + assert chain.time() >= chain_now + half_period_size_seconds_to_skip + + +# NOTE: helper uses UTC time format which fits to the blockchain timezone +def get_timestamp_from_date(year, month, day, hour=0, min=0, sec=0): + return datetime(year, month, day, hour, min, sec, tzinfo=timezone.utc).timestamp() diff --git a/utils/vote_for_new_factories.py b/utils/vote_for_new_factories.py index a8a8f92e..32e03030 100644 --- a/utils/vote_for_new_factories.py +++ b/utils/vote_for_new_factories.py @@ -1,58 +1,57 @@ +import brownie from typing import NamedTuple, List, Dict from utils import lido, log from utils.config import prompt_bool from utils.evm_script import encode_call_script -from brownie import (Contract, EasyTrack) +from brownie import Contract, EasyTrack + class FactoryToAdd(NamedTuple): factory: Contract permissions: str + class FactoryToRemove(NamedTuple): factory: Contract + def create_voting_on_new_factories( easy_track: EasyTrack, factories_to_add: List[FactoryToAdd], factories_to_remove: List[FactoryToRemove], network: str, - tx_params: Dict[str, str] + tx_params: Dict[str, str], ) -> int: factories_evm_script: str = encode_call_script( [ ( easy_track.address, - easy_track.removeEVMScriptFactory.encode_input( - elem.factory - ) + easy_track.removeEVMScriptFactory.encode_input(elem.factory), ) for elem in factories_to_remove - ] + - [ + ] + + [ ( easy_track.address, - easy_track.addEVMScriptFactory.encode_input( - elem.factory, - elem.permissions - ) + easy_track.addEVMScriptFactory.encode_input(elem.factory, elem.permissions), ) for elem in factories_to_add ] ) - description: str = 'Omnibus vote:' + description: str = "Omnibus vote:" item_id: int = 1 for elem in factories_to_remove: - description += f'{item_id}) Remove {elem.factory} factory;' + description += f"{item_id}) Remove {elem.factory} factory;" item_id = item_id + 1 for elem in factories_to_add: - description += f'{item_id}) Add {elem.factory} factory;' + description += f"{item_id}) Add {elem.factory} factory;" item_id = item_id + 1 - description = description[:-1] + '.' + description = description[:-1] + "." - print(description.replace(';', '\n')) + print(description.replace(";", "\n")) print("Proceed to create vote? [yes/no]: ") @@ -60,10 +59,11 @@ def create_voting_on_new_factories( log.nb("Aborting") return -1 - vote_id, _ = lido.create_voting( + lido_contracts = lido.contracts(network=brownie.network.show_active()) + + vote_id, _ = lido_contracts.create_voting( evm_script=factories_evm_script, description=description, - network=network, tx_params=tx_params, ) return vote_id diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..e36f9a6d --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2307 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@openzeppelin/contracts-v4.3.2@npm:@openzeppelin/contracts@4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.2.tgz#ff80affd6d352dbe1bbc5b4e1833c41afd6283b6" + integrity sha512-AybF1cesONZStg5kWf6ao9OlqTZuPqddvprc0ky7lrUVOjXeKpmQ2Y9FK+6ygxasb+4aic4O5pneFBfwVsRRRg== + +"@solidity-parser/parser@^0.14.2": + version "0.14.3" + resolved "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz" + integrity sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@trufflesuite/bigint-buffer@1.1.10": + version "1.1.10" + resolved "https://registry.npmjs.org/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz" + integrity sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw== + dependencies: + node-gyp-build "4.4.0" + +"@trufflesuite/uws-js-unofficial@20.30.0-unofficial.0": + version "20.30.0-unofficial.0" + resolved "https://registry.yarnpkg.com/@trufflesuite/uws-js-unofficial/-/uws-js-unofficial-20.30.0-unofficial.0.tgz#2fbc2f8ef7e82fbeea6abaf7e8a9d42a02b479d3" + integrity sha512-r5X0aOQcuT6pLwTRLD+mPnAM/nlKtvIK4Z+My++A8tTOR0qTjNRx8UB8jzRj3D+p9PMAp5LnpCUUGmz7/TppwA== + dependencies: + ws "8.13.0" + optionalDependencies: + bufferutil "4.0.7" + utf-8-validate "6.0.3" + +"@types/bn.js@^5.1.0": + version "5.1.0" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== + dependencies: + "@types/node" "*" + +"@types/lru-cache@5.1.1": + version "5.1.1" + resolved "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/minimatch@^3.0.3": + version "3.0.5" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/node@*": + version "17.0.0" + resolved "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz" + integrity sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw== + +"@types/seedrandom@3.0.1": + version "3.0.1" + resolved "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-3.0.1.tgz" + integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw== + +abstract-level@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" + integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + +abstract-leveldown@7.2.0, abstract-leveldown@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#08d19d4e26fb5be426f7a57004851b39e1795a2e" + integrity sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ== + dependencies: + buffer "^6.0.3" + catering "^2.0.0" + is-buffer "^2.0.5" + level-concat-iterator "^3.0.0" + level-supports "^2.0.1" + queue-microtask "^1.2.3" + +ajv@^5.2.2: + version "5.5.2" + resolved "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz" + integrity sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw== + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz" + integrity sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA== + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz" + integrity sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ== + +array-differ@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz" + integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" + integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== + dependencies: + array-uniq "^1.0.1" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz" + integrity sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== + +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +async-each@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-eventemitter@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== + dependencies: + async "^2.4.0" + +async@^2.4.0: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz" + integrity sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw== + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz" + integrity sha512-7Rfk377tpSM9TWBEeHs0FlDZGoAIei2V/4MdZJoFMBFAK6BqLpxAIUepGRHGdPFgGsLb02PXovC4qddyHvQqTg== + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@4.0.5: + version "4.0.5" + resolved "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz" + integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A== + dependencies: + node-gyp-build "^4.3.0" + +bufferutil@4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + dependencies: + node-gyp-build "^4.3.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz" + integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== + +catering@^2.0.0, catering@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/catering/-/catering-2.1.0.tgz" + integrity sha512-M5imwzQn6y+ODBfgi+cfgZv2hIUI6oYU/0f35Mdb1ujGeqeoI5tOnl9Q13DTH7LW+7er+NYq8stNOKZD/Z3U/A== + dependencies: + queue-tick "^1.0.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^1.6.0: + version "1.7.0" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz" + integrity sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg== + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colors@^1.1.2: + version "1.4.0" + resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +commander@2.11.0: + version "2.11.0" + resolved "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== + +commander@^2.9.0: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz" + integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +diff@3.3.1: + version "3.3.1" + resolved "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz" + integrity sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww== + +diff@^3.5.0: + version "3.5.0" + resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emittery@0.10.0: + version "0.10.0" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.10.0.tgz" + integrity sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ== + +emoji-regex@^10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz" + integrity sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +eol@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz" + integrity sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg== + +errno@^0.1.2: + version "0.1.8" + resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +escape-string-regexp@1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +ethlint@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/ethlint/-/ethlint-1.2.5.tgz" + integrity sha512-x2nKK98zmd72SFWL3Ul1S6scWYf5QqG221N6/mFNMO661g7ASvTRINGIWVvHzsvflW6y4tvgMSjnTN5RCTuZug== + dependencies: + ajv "^5.2.2" + chokidar "^1.6.0" + colors "^1.1.2" + commander "^2.9.0" + diff "^3.5.0" + eol "^0.9.1" + js-string-escape "^1.0.1" + lodash "^4.14.2" + sol-digger "0.0.2" + sol-explore "1.6.1" + solium-plugin-security "0.1.1" + solparse "2.2.8" + text-table "^0.2.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz" + integrity sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw== + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz" + integrity sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA== + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz" + integrity sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA== + dependencies: + fill-range "^2.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz" + integrity sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg== + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz" + integrity sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz" + integrity sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ== + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== + dependencies: + locate-path "^2.0.0" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz" + integrity sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw== + dependencies: + for-in "^1.0.1" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^1.0.0: + version "1.2.13" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +ganache@^7.9.1: + version "7.9.1" + resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.9.1.tgz#94f8518215c7989ff5fd542db80bd47d7c7da786" + integrity sha512-Tqhd4J3cpiLeYTD6ek/zlchSB107IVPMIm4ypyg+xz1sdkeALUnYYZnmY4Bdjqj3i6QwtlZPCu7U4qKy7HlWTA== + dependencies: + "@trufflesuite/bigint-buffer" "1.1.10" + "@trufflesuite/uws-js-unofficial" "20.30.0-unofficial.0" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "5.1.1" + "@types/seedrandom" "3.0.1" + abstract-level "1.0.3" + abstract-leveldown "7.2.0" + async-eventemitter "0.2.4" + emittery "0.10.0" + keccak "3.0.2" + leveldown "6.1.0" + secp256k1 "4.0.3" + optionalDependencies: + bufferutil "4.0.5" + utf-8-validate "5.0.7" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + +get-stream@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz" + integrity sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA== + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz" + integrity sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w== + dependencies: + is-glob "^2.0.0" + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.4: + version "4.2.10" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +growl@1.10.3: + version "1.10.3" + resolved "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz" + integrity sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q== + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz" + integrity sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/he/-/he-1.1.1.tgz" + integrity sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +husky@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz" + integrity sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ== + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.1.4: + version "5.2.0" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz" + integrity sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg== + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz" + integrity sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA== + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz" + integrity sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" + 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.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz" + integrity sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg== + dependencies: + is-extglob "^1.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz" + integrity sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg== + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz" + integrity sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ== + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz" + integrity sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz" + integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz" + integrity sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA== + +junk@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz" + integrity sha512-3KF80UaaSSxo8jVnRYtMKNGFOoVPBdkkVPsw+Ad0y4oxKXPduS6G6iHkrf69yJVff/VAaYXkV42rtZ7daJxU3w== + +keccak@3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz" + integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + +level-concat-iterator@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz" + integrity sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ== + dependencies: + catering "^2.1.0" + +level-supports@^2.0.1: + version "2.1.0" + resolved "https://registry.npmjs.org/level-supports/-/level-supports-2.1.0.tgz" + integrity sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA== + +level-supports@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== + +level-transcoder@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" + integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== + dependencies: + buffer "^6.0.3" + module-error "^1.0.1" + +leveldown@6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/leveldown/-/leveldown-6.1.0.tgz" + integrity sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w== + dependencies: + abstract-leveldown "^7.2.0" + napi-macros "~2.0.0" + node-gyp-build "^4.3.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash@^4.14.2, lodash@^4.17.14: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +maximatch@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz" + integrity sha512-9ORVtDUFk4u/NFfo0vG/ND/z7UQCVZBL539YW0+U1I7H1BkZwizcPx5foFv7LCPcBnm2U6RjFnQOsIvN4/Vm2A== + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz" + integrity sha512-nOBDrc/wgpkd3X/JOhMqYR+/eLqlfLP4oQfoBA6QExIxEl+GU01oyEkwWyueyO8110pUKijtiHGhEmYoOn88oQ== + dependencies: + mimic-fn "^1.0.0" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz" + integrity sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA== + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.0, minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + integrity sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q== + +minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" + integrity sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA== + dependencies: + minimist "0.0.8" + +mkdirp@^0.5.1: + version "0.5.6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@^4.0.1: + version "4.1.0" + resolved "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz" + integrity sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA== + dependencies: + browser-stdout "1.3.0" + commander "2.11.0" + debug "3.1.0" + diff "3.3.1" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.3" + he "1.1.1" + mkdirp "0.5.1" + supports-color "4.4.0" + +module-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" + integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== + +mri@^1.1.5: + version "1.2.0" + resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" + integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +multimatch@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz" + integrity sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ== + dependencies: + "@types/minimatch" "^3.0.3" + array-differ "^3.0.0" + array-union "^2.1.0" + arrify "^2.0.1" + minimatch "^3.0.4" + +nan@^2.12.1: + version "2.16.0" + resolved "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +napi-macros@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz" + integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== + +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-gyp-build@4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz" + integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== + +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + +normalize-path@^2.0.0, normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz" + integrity sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA== + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz" + integrity sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA== + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +pegjs@^0.10.0: + version "0.10.0" + resolved "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz" + integrity sha512-qI5+oFNEGi3L5HAxDwN2LA4Gg7irF70Zs25edhjld9QemOgp0CbvMtbFcMvFtEo1OityPrcCzkQFB8JP/hxgow== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz" + integrity sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ== + +prettier-plugin-solidity@^1.0.0-beta.10: + version "1.0.0-dev.22" + resolved "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-dev.22.tgz" + integrity sha512-0v+O2/sqq6WMlZ2TsnRBXaNmKF4zANn0uLLWuvNra4BjmKUtp33EZ4AVKB26fzWy14BkVGeJfPAtKry0x3SFfQ== + dependencies: + "@solidity-parser/parser" "^0.14.2" + emoji-regex "^10.1.0" + escape-string-regexp "^4.0.0" + semver "^7.3.7" + solidity-comments-extractor "^0.0.7" + string-width "^4.2.3" + +prettier@^2.3.0: + version "2.7.1" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== + +pretty-quick@^3.1.0: + version "3.1.3" + resolved "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz" + integrity sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA== + dependencies: + chalk "^3.0.0" + execa "^4.0.0" + find-up "^4.1.0" + ignore "^5.1.4" + mri "^1.1.5" + multimatch "^4.0.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +promise@^7.0.1: + version "7.3.1" + resolved "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +queue-microtask@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +queue-tick@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.0.tgz" + integrity sha512-ULWhjjE8BmiICGn3G8+1L9wFpERNxkf8ysxkAer4+TFdRefDaXOCV5m92aMB9FtBVmn/8sETXLXY6BfW7hyaWQ== + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +readable-stream@^2.0.2: + version "2.3.7" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +recursive-copy@^2.0.13: + version "2.0.14" + resolved "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.14.tgz" + integrity sha512-K8WNY8f8naTpfbA+RaXmkaQuD1IeW9EgNEfyGxSqqTQukpVtoOKros9jUqbpEsSw59YOmpd8nCBgtqJZy5nvog== + dependencies: + errno "^0.1.2" + graceful-fs "^4.1.4" + junk "^1.0.1" + maximatch "^0.1.0" + mkdirp "^0.5.1" + pify "^2.3.0" + promise "^7.0.1" + rimraf "^2.7.1" + slash "^1.0.0" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.7.1: + version "2.7.1" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + +secp256k1@4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +semver@^7.3.7: + version "7.3.7" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz" + integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sol-digger@0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/sol-digger/-/sol-digger-0.0.2.tgz" + integrity sha512-oqrw1E/X2WWYUYCzKDM5INDDH2nWOWos4p2Cw2OF52qoZcTDzlKMJQ5pJFXKOCADCg6KggBO5WYE/vNb+kJ0Hg== + +sol-explore@1.6.1: + version "1.6.1" + resolved "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.1.tgz" + integrity sha512-cmwg7l+QLj2LE3Qvwrdo4aPYcNYY425+bN5VPkgCjkO0CiSz33G5vM5BmMZNrfd/6yNGwcm0KtwDJmh5lUElEQ== + +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + +solium-plugin-security@0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/solium-plugin-security/-/solium-plugin-security-0.1.1.tgz" + integrity sha512-kpLirBwIq4mhxk0Y/nn5cQ6qdJTI+U1LO3gpoNIcqNaW+sI058moXBe2UiHs+9wvF9IzYD49jcKhFTxcR9u9SQ== + +solparse@2.2.8: + version "2.2.8" + resolved "https://registry.npmjs.org/solparse/-/solparse-2.2.8.tgz" + integrity sha512-Tm6hdfG72DOxD40SD+T5ddbekWglNWjzDRSNq7ZDIOHVsyaJSeeunUuWNj4DE7uDrJK3tGQuX0ZTDZWNYsGPMA== + dependencies: + mocha "^4.0.1" + pegjs "^0.10.0" + yargs "^10.0.3" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + 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.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +supports-color@4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz" + integrity sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ== + dependencies: + has-flag "^2.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +utf-8-validate@5.0.7: + version "5.0.7" + resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz" + integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q== + dependencies: + node-gyp-build "^4.3.0" + +utf-8-validate@6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-6.0.3.tgz#7d8c936d854e86b24d1d655f138ee27d2636d777" + integrity sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA== + dependencies: + node-gyp-build "^4.3.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" + integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" + integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz" + integrity sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ== + dependencies: + camelcase "^4.1.0" + +yargs@^10.0.3: + version "10.1.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz" + integrity sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^8.1.0"