diff --git a/ethereum/.editorconfig b/.editorconfig similarity index 100% rename from ethereum/.editorconfig rename to .editorconfig diff --git a/ethereum/.eslintrc b/.eslintrc similarity index 88% rename from ethereum/.eslintrc rename to .eslintrc index 149807292..20cae5175 100644 --- a/ethereum/.eslintrc +++ b/.eslintrc @@ -8,5 +8,8 @@ "import/namespace": "off", "import/no-unresolved": "off", "import/order": "off" - } + }, + "ignorePatterns": [ + "**/lib/*" + ] } diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 2f0cdb3e8..76dfb3f2d 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -6,15 +6,11 @@ RED='\033[0;31m' # Check that the code is formatted in the given directory provided in the first argument function check_prettier { - cd $1 if ! yarn prettier:check; then echo "${RED}Commit error! Cannot commit unformatted code!${NC}" - echo "Prettier errors found in the ${CYAN}$(pwd)${NC} directory." - echo "Please format the code via ${CYAN}cd $1 && yarn prettier:fix${NC}!" + echo "Prettier errors found. Please format the code via ${CYAN}yarn prettier:fix${NC}!" exit 1 fi - cd .. } -check_prettier "ethereum" -check_prettier "zksync" +check_prettier diff --git a/.githooks/pre-push b/.githooks/pre-push index de780c1b7..214d2f641 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -6,15 +6,11 @@ RED='\033[0;31m' # Checking that the code is linted and formatted in the given directory provided in the first argument function check_lint { - cd $1 if ! yarn lint:check; then echo "${RED}Push error! Cannot push unlinted code!${NC}" - echo "Lint errors found in the ${CYAN}$(pwd)${NC} directory." - echo "Please lint the code via ${CYAN}cd $1 && yarn lint:fix${NC} and/or fix the errors manually!" + echo "Lint errors found. Please lint the code via ${CYAN}yarn lint:fix${NC} and/or fix the errors manually!" exit 1 fi - cd .. } -check_lint "ethereum" -check_lint "zksync" +check_lint diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 163e439d5..ecc2e3dd8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,9 +1,9 @@ --- name: Scripts-Related Bug Report about: Use this template for reporting script-related bugs. For contract-related bugs, see our security policy. -title: '' +title: "" labels: bug -assignees: '' +assignees: "" --- ### 🐛 Script Bug Report diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index d921e066c..f04164903 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,9 +1,9 @@ --- name: Feature request about: Use this template for requesting features -title: '' +title: "" labels: feat -assignees: '' +assignees: "" --- ### 🌟 Feature Request diff --git a/.github/workflows/buld-release.yaml b/.github/workflows/buld-release.yaml new file mode 100644 index 000000000..426b0f966 --- /dev/null +++ b/.github/workflows/buld-release.yaml @@ -0,0 +1,49 @@ +name: Build and release + +on: + push: + branches: + - "*" + +jobs: + build-contracts: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Init + id: init + run: | + yarn + echo "release_tag=$(echo ${GITHUB_REF#refs/heads/})-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Build contracts + run: | + yarn l1 build + yarn l2 build + yarn sc build + + - name: Prepare artifacts + run: | + tar -czvf l1-contracts.tar.gz ./l1-contracts + tar -czvf l2-contracts.tar.gz ./l2-contracts + tar -czvf system-contracts.tar.gz ./system-contracts + + - name: Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ steps.init.outputs.release_tag }} + fail_on_unmatched_files: true + body: "" + files: | + l1-contracts.tar.gz + l2-contracts.tar.gz + system-contracts.tar.gz diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 524b178bb..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,275 +0,0 @@ -name: CI - -on: pull_request - -jobs: - lint-l1: - runs-on: ubuntu-latest - - defaults: - run: - working-directory: ethereum - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - cache-dependency-path: ethereum/yarn.lock - - - name: Install yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Lint - run: yarn lint:check - - lint-l2: - runs-on: ubuntu-latest - - defaults: - run: - working-directory: zksync - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - cache-dependency-path: zksync/yarn.lock - - - name: Install yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Lint - run: yarn lint:check - - build-l1: - runs-on: ubuntu-latest - - defaults: - run: - working-directory: ethereum - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - cache-dependency-path: ethereum/yarn.lock - - - name: Install yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Build artifacts - run: yarn build - - - name: Create cache - uses: actions/cache/save@v3 - with: - key: artifacts-${{ github.sha }} - path: | - ethereum/artifacts - ethereum/cache - ethereum/typechain - - build-l2: - runs-on: ubuntu-latest - - defaults: - run: - working-directory: zksync - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - cache-dependency-path: zksync/yarn.lock - - - name: Install yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Build artifacts - run: yarn build - - - name: Create cache - uses: actions/cache/save@v3 - with: - key: artifacts-zk-${{ github.sha }} - path: | - zksync/artifacts-zk - zksync/cache-zk - zksync/typechain - - test-hardhat-l1: - needs: [build-l1, lint-l1] - runs-on: ubuntu-latest - - defaults: - run: - working-directory: ethereum - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - cache-dependency-path: ethereum/yarn.lock - - - name: Install yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Restore artifacts cache - uses: actions/cache/restore@v3 - with: - fail-on-cache-miss: true - key: artifacts-${{ github.sha }} - path: | - ethereum/artifacts - ethereum/cache - ethereum/typechain - - - name: Run tests - run: yarn test --no-compile - - test-foundry-l1: - needs: [build-l1, lint-l1] - runs-on: ubuntu-latest - - defaults: - run: - working-directory: ethereum - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - with: - submodules: "recursive" - - - name: "Install Foundry" - uses: "foundry-rs/foundry-toolchain@v1" - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - cache-dependency-path: ethereum/yarn.lock - - - name: Install yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Restore artifacts cache - uses: actions/cache/restore@v3 - with: - fail-on-cache-miss: true - key: artifacts-${{ github.sha }} - path: | - ethereum/artifacts - ethereum/cache - ethereum/typechain - - - name: Run tests - run: forge test - - test-hardhat-l2: - needs: [build-l2, lint-l2] - runs-on: ubuntu-latest - - defaults: - run: - working-directory: zksync - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - with: - submodules: "recursive" - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - cache-dependency-path: zksync/yarn.lock - - - name: Install yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Restore artifacts cache - uses: actions/cache/restore@v3 - with: - fail-on-cache-miss: true - key: artifacts-zk-${{ github.sha }} - path: | - zksync/artifacts-zk - zksync/cache-zk - zksync/typechain - - - name: Run Era test node - uses: dutterbutter/era-test-node-action@latest - - - name: Run tests - run: yarn hardhat test - - check-verifier-generator: - runs-on: ubuntu-latest - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - with: - submodules: "recursive" - - - name: Install rust - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.72.0 - - - name: Generete Verifier.sol - working-directory: tools - run: cargo run - - - name: Compare - run: diff tools/data/Verifier.sol ethereum/contracts/zksync/Verifier.sol diff --git a/.github/workflows/l1-contracts-ci.yaml b/.github/workflows/l1-contracts-ci.yaml new file mode 100644 index 000000000..394eabaef --- /dev/null +++ b/.github/workflows/l1-contracts-ci.yaml @@ -0,0 +1,138 @@ +name: L1 contracts CI + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Build artifacts + run: yarn l1 build + + - name: Create cache + uses: actions/cache/save@v3 + with: + key: artifacts-l1-${{ github.sha }} + path: | + l1-contracts/artifacts + l1-contracts/cache + l1-contracts/typechain + + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Lint + run: yarn lint:check + + test-foundry: + needs: [build, lint] + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Use Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-l1-${{ github.sha }} + path: | + l1-contracts/artifacts + l1-contracts/cache + l1-contracts/typechain + + - name: Run tests + run: yarn l1 test:foundry + + test-hardhat: + needs: [build, lint] + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-l1-${{ github.sha }} + path: | + l1-contracts/artifacts + l1-contracts/cache + l1-contracts/typechain + + - name: Run tests + run: yarn l1 test --no-compile + + check-verifier-generator: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install rust + uses: actions-rs/toolchain@v1 + with: + toolchain: 1.72.0 + + - name: Generate Verifier.sol + working-directory: tools + run: cargo run + + - name: Compare + run: diff tools/data/Verifier.sol l1-contracts/contracts/zksync/Verifier.sol diff --git a/.github/workflows/l2-contracts-ci.yaml b/.github/workflows/l2-contracts-ci.yaml new file mode 100644 index 000000000..e99569393 --- /dev/null +++ b/.github/workflows/l2-contracts-ci.yaml @@ -0,0 +1,87 @@ +name: L2 contracts CI + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Build artifacts + run: yarn l2 build + + - name: Create cache + uses: actions/cache/save@v3 + with: + key: artifacts-l2-${{ github.sha }} + path: | + l2-contracts/artifacts-zk + l2-contracts/cache-zk + l2-contracts/typechain + + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Lint + run: yarn lint:check + + test: + needs: [build, lint] + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-l2-${{ github.sha }} + path: | + l2-contracts/artifacts-zk + l2-contracts/cache-zk + l2-contracts/typechain + + - name: Run Era test node + uses: dutterbutter/era-test-node-action@v0.1.3 + + - name: Run tests + run: yarn l2 test diff --git a/.github/workflows/label-external-contributions.yaml b/.github/workflows/label-external-contributions.yaml new file mode 100644 index 000000000..de9f2439c --- /dev/null +++ b/.github/workflows/label-external-contributions.yaml @@ -0,0 +1,38 @@ +name: Workflow to label external contributions + +on: + pull_request_target: + types: [opened, ready_for_review] + +permissions: + contents: read + pull-requests: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - name: Add external-contribution label + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH") + REPO_FULL_NAME=$(jq --raw-output .repository.full_name "$GITHUB_EVENT_PATH") + IS_FORK=$(jq --raw-output .pull_request.head.repo.fork "$GITHUB_EVENT_PATH") + + if [[ "$IS_FORK" == "true" ]]; then + echo "This PR is created from a fork." + HTTP_STATUS=$(curl -o /dev/null -s -w "%{http_code}\n" \ + -X POST \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$REPO_FULL_NAME/issues/$PR_NUMBER/labels" \ + -d '{"labels": ["external-contribution"]}') + + if [[ $HTTP_STATUS -ge 300 ]]; then + echo "Failed to add label to PR, exiting." + exit 1 + fi + else + echo "This PR is not created from a fork." + fi diff --git a/.github/workflows/nodejs-license.yaml b/.github/workflows/nodejs-license.yaml index 4b9c74f69..87ea4248f 100644 --- a/.github/workflows/nodejs-license.yaml +++ b/.github/workflows/nodejs-license.yaml @@ -8,6 +8,7 @@ env: BSD; ISC; Apache-2.0; + Apache 2.0; MPL-2.0; LGPL-3.0; LGPL-3.0-or-later; @@ -20,7 +21,7 @@ env: WTFPL; Unlicense; # It has to be one line, there must be no space between packages. - EXCLUDE_PACKAGES: testrpc@0.0.1;uuid@2.0.1; + EXCLUDE_PACKAGES: testrpc@0.0.1;uuid@2.0.1;era-contracts@0.1.0; jobs: generate-matrix: diff --git a/.github/workflows/system-contracts-ci.yaml b/.github/workflows/system-contracts-ci.yaml new file mode 100644 index 000000000..50bf407d2 --- /dev/null +++ b/.github/workflows/system-contracts-ci.yaml @@ -0,0 +1,157 @@ +name: System contracts CI + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Build artifacts + run: yarn sc build + + - name: Create cache + uses: actions/cache/save@v3 + with: + key: artifacts-system-${{ github.sha }} + path: | + system-contracts/artifacts-zk + system-contracts/cache-zk + system-contracts/typechain + system-contracts/contracts-preprocessed + system-contracts/bootloader/build + + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Run lint + run: yarn lint:check + + test-bootloader: + needs: [build, lint] + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Install rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: nightly-2023-04-17 + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-system-${{ github.sha }} + path: | + system-contracts/artifacts-zk + system-contracts/cache-zk + system-contracts/typechain + system-contracts/contracts-preprocessed + system-contracts/bootloader/build + + - name: Run bootloader tests + run: | + cd system-contracts/bootloader/test_infra + cargo run + + test-contracts: + needs: [build, lint] + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Use era-test-node for testing + uses: dutterbutter/era-test-node-action@v0.1.3 + with: + releaseTag: v0.0.1-alpha.boojum + + - name: Install dependencies + run: yarn + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-system-${{ github.sha }} + path: | + system-contracts/artifacts-zk + system-contracts/cache-zk + system-contracts/typechain + system-contracts/contracts-preprocessed + system-contracts/bootloader/build + + - name: Run tests + run: yarn sc test + + - name: Print output logs of era_test_node + if: always() + run: cat era_test_node.log + + check-hashes: + needs: [build] + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-system-${{ github.sha }} + path: | + system-contracts/artifacts-zk + system-contracts/cache-zk + system-contracts/typechain + system-contracts/contracts-preprocessed + system-contracts/bootloader/build + + - name: Check hashes + run: yarn sc calculate-hashes:check diff --git a/.gitignore b/.gitignore index 79fa3b033..0f3f8b718 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,18 @@ +.DS_Store .idea -tools/target -tools/data/Verifier.sol \ No newline at end of file +.vscode +artifacts-forge/ +artifacts-zk/ +artifacts/ +build/ +cache-forge/ +cache-zk/ +cache/ +contracts-preprocessed/ +era_test_node.log* +node_modules/ +target/ +tools/data/Verifier.sol +typechain/ +yarn-debug.log* +yarn-error.log* diff --git a/.gitmodules b/.gitmodules index 9abc38c54..e0abe69d3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ -[submodule "ethereum/lib/forge-std"] - path = ethereum/lib/forge-std +[submodule "l1-contracts/lib/forge-std"] + path = l1-contracts/lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "l1-contracts/lib/murky"] + path = l1-contracts/lib/murky + url = https://github.com/dmfxyz/murky diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 000000000..23c081c49 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,12 @@ +# root +node_modules + +# l1-contracts +l1-contracts/lib +l1-contracts/node_modules + +# l2-contracts +l2-contracts/node_modules + +# system-contracts +system-contracts/node_modules diff --git a/ethereum/.markdownlintrc b/.markdownlintrc similarity index 100% rename from ethereum/.markdownlintrc rename to .markdownlintrc diff --git a/ethereum/.nvmrc b/.nvmrc similarity index 100% rename from ethereum/.nvmrc rename to .nvmrc diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..2c9519237 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +tools/data +l1-contracts/lib +system-contracts/contracts/openzeppelin +system-contracts/contracts/Constants.sol diff --git a/ethereum/.prettierrc.js b/.prettierrc.js similarity index 100% rename from ethereum/.prettierrc.js rename to .prettierrc.js diff --git a/ethereum/.solhint.json b/.solhint.json similarity index 100% rename from ethereum/.solhint.json rename to .solhint.json diff --git a/.solhintignore b/.solhintignore new file mode 100644 index 000000000..1688beeef --- /dev/null +++ b/.solhintignore @@ -0,0 +1,15 @@ +# root +node_modules + +# l1-contracts +l1-contracts/cache +l1-contracts/lib +l1-contracts/node_modules + +# l2-contracts +l2-contracts/cache-zk +l2-contracts/node_modules + +# system-contracts +system-contracts/contracts/openzeppelin +system-contracts/contracts/Constants.sol diff --git a/docs/Overview.md b/docs/Overview.md index 72b4021d1..7b1b15658 100644 --- a/docs/Overview.md +++ b/docs/Overview.md @@ -78,12 +78,11 @@ Each upgrade consists of two steps: - Upgrade Proposal - The governor can schedule upgrades in two different manners: - Fully transparent data. All implementation contracts and migration contracts are known to the community. The governor must wait -for the timelock to execute the upgrade. + for the timelock to execute the upgrade. - Shadow upgrade. The governor only shows the commitment for the upgrade. The upgrade can be executed only with security council -approval without timelock. + approval without timelock. - Upgrade execution - perform the upgrade that was proposed. - #### MailboxFacet The facet that handles L2 <-> L1 communication, an overview for which can be found in @@ -119,7 +118,6 @@ function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Ad l2Address = address(uint160(l1Address) + offset); } } - ``` For most of the rollups the address aliasing needs to prevent cross-chain exploits that would otherwise be possible if @@ -169,14 +167,14 @@ Each L2 -> L1 system log will have a key that is part of the following: ```solidity enum SystemLogKey { - L2_TO_L1_LOGS_TREE_ROOT_KEY, - TOTAL_L2_TO_L1_PUBDATA_KEY, - STATE_DIFF_HASH_KEY, - PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY, - PREV_BATCH_HASH_KEY, - CHAINED_PRIORITY_TXN_HASH_KEY, - NUMBER_OF_LAYER_1_TXS_KEY, - EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY + L2_TO_L1_LOGS_TREE_ROOT_KEY, + TOTAL_L2_TO_L1_PUBDATA_KEY, + STATE_DIFF_HASH_KEY, + PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY, + PREV_BATCH_HASH_KEY, + CHAINED_PRIORITY_TXN_HASH_KEY, + NUMBER_OF_LAYER_1_TXS_KEY, + EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY } ``` @@ -260,11 +258,6 @@ validator can prove the already commited batches regardless of the mentioned tim to the `proveBatches` function) will be propogated to the zkSync contract. After, the `delay` is elapsed, the validator is allowed to call `executeBatches` to propogate the same calldata to zkSync contract. -#### Allowlist - -The auxiliary contract controls the permission access list. It is used in bridges and diamond proxies to control which -addresses can interact with them in the Alpha release. - ### L2 specifics #### Deployment @@ -295,26 +288,3 @@ Thus: - L2 contracts are deployed by bytecode hash, not by full bytecode - Factory dependencies - list of bytecode hashes that can be deployed on L2 - Address derivation for `create`/`create2` on L1 and L2 is different - -### Deposit Limitation - -The amount of deposit can be limited. This limitation is applied on an account level and is not time-based. In other -words, each account cannot deposit more than the cap defined. The tokens and the cap can be set through governance -transactions. Moreover, there is an allow listing mechanism as well (only some allow listed accounts can call some -specific functions). So, the combination of deposit limitation and allow listing leads to limiting the deposit of the -allow listed account to be less than the defined cap. - -```solidity -struct Deposit { - bool depositLimitation; - uint256 depositCap; -} - -``` - -Currently, the limit is used only for blocking deposits of the specific token (turning on the limitation and setting the -limit to zero). And on the near future, this functionality will be completely removed. - -See the -[documentation](https://era.zksync.io/docs/dev/building-on-zksync/contracts/contract-development.html#solidity-vyper-support) -to read more! diff --git a/ethereum/.gitignore b/ethereum/.gitignore deleted file mode 100644 index b83d90dcd..000000000 --- a/ethereum/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/build -/artifacts -/cache -/typechain -node_modules -./contracts/DS_Store -/artifacts-forge -/cache-forge -yarn-debug.log* -yarn-error.log* diff --git a/ethereum/.markdownlintignore b/ethereum/.markdownlintignore deleted file mode 100644 index 3063f07d5..000000000 --- a/ethereum/.markdownlintignore +++ /dev/null @@ -1,2 +0,0 @@ -lib -node_modules diff --git a/ethereum/.prettierignore b/ethereum/.prettierignore deleted file mode 100644 index f42f470df..000000000 --- a/ethereum/.prettierignore +++ /dev/null @@ -1,6 +0,0 @@ -artifacts -artifacts-forge -cache -cache-forge -lib -node_modules diff --git a/ethereum/.solhintignore b/ethereum/.solhintignore deleted file mode 100644 index 05cfef15f..000000000 --- a/ethereum/.solhintignore +++ /dev/null @@ -1,3 +0,0 @@ -cache -lib -node_modules diff --git a/ethereum/contracts/common/AllowList.sol b/ethereum/contracts/common/AllowList.sol deleted file mode 100644 index c10a9615b..000000000 --- a/ethereum/contracts/common/AllowList.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import "@openzeppelin/contracts/access/Ownable2Step.sol"; - -import "./interfaces/IAllowList.sol"; -import "./libraries/UncheckedMath.sol"; - -/// @author Matter Labs -/// @custom:security-contact security@matterlabs.dev -/// @notice The smart contract that stores the permissions to call the function on different contracts. -/// @dev The contract is fully controlled by the owner, that can grant and revoke any permissions at any time. -/// @dev The permission list has three different modes: -/// - Closed. The contract cannot be called by anyone. -/// - SpecialAccessOnly. Only some contract functions can be called by specifically granted addresses. -/// - Public. Access list to call any function from the target contract by any caller -contract AllowList is IAllowList, Ownable2Step { - using UncheckedMath for uint256; - - /// @notice The Access mode by which it is decided whether the caller has access - mapping(address => AccessMode) public getAccessMode; - - /// @notice The mapping that stores permissions to call the function on the target address by the caller - /// @dev caller => target => function signature => permission to call target function for the given caller address - mapping(address => mapping(address => mapping(bytes4 => bool))) public hasSpecialAccessToCall; - - /// @dev The mapping L1 token address => struct Deposit - mapping(address => Deposit) public tokenDeposit; - - constructor(address _initialOwner) { - _transferOwnership(_initialOwner); - } - - /// @return Whether the caller can call the specific function on the target contract - /// @param _caller The caller address, who is granted access - /// @param _target The address of the smart contract which is called - /// @param _functionSig The function signature (selector), access to which need to check - function canCall(address _caller, address _target, bytes4 _functionSig) external view returns (bool) { - AccessMode accessMode = getAccessMode[_target]; - return - accessMode == AccessMode.Public || - (accessMode == AccessMode.SpecialAccessOnly && hasSpecialAccessToCall[_caller][_target][_functionSig]); - } - - /// @notice Set the permission mode to call the target contract - /// @param _target The address of the smart contract, of which access to the call is to be changed - /// @param _accessMode Whether no one, any or only some addresses can call the target contract - function setAccessMode(address _target, AccessMode _accessMode) external onlyOwner { - _setAccessMode(_target, _accessMode); - } - - /// @notice Set many permission modes to call the target contracts - /// @dev Analogous to function `setAccessMode` but performs a batch of changes - /// @param _targets The array of smart contract addresses, of which access to the call is to be changed - /// @param _accessModes The array of new permission modes, whether no one, any or only some addresses can call the - /// target contract - function setBatchAccessMode(address[] calldata _targets, AccessMode[] calldata _accessModes) external onlyOwner { - uint256 targetsLength = _targets.length; - require(targetsLength == _accessModes.length, "yg"); // The size of arrays should be equal - - for (uint256 i = 0; i < targetsLength; i = i.uncheckedInc()) { - _setAccessMode(_targets[i], _accessModes[i]); - } - } - - /// @dev Changes access mode and emit the event if the access was changed - function _setAccessMode(address _target, AccessMode _accessMode) internal { - AccessMode accessMode = getAccessMode[_target]; - - if (accessMode != _accessMode) { - getAccessMode[_target] = _accessMode; - emit UpdateAccessMode(_target, accessMode, _accessMode); - } - } - - /// @notice Set many permissions to call the function on the contract to the specified caller address - /// @param _callers The array of caller addresses, who are granted access - /// @param _targets The array of smart contract addresses, of which access to the call are to be changed - /// @param _functionSigs The array of function signatures (selectors), access to which need to be changed - /// @param _enables The array of boolean flags, whether enable or disable the function access to the corresponding - /// target address - function setBatchPermissionToCall( - address[] calldata _callers, - address[] calldata _targets, - bytes4[] calldata _functionSigs, - bool[] calldata _enables - ) external onlyOwner { - uint256 callersLength = _callers.length; - - // The size of arrays should be equal - require(callersLength == _targets.length, "yw"); - require(callersLength == _functionSigs.length, "yx"); - require(callersLength == _enables.length, "yy"); - - for (uint256 i = 0; i < callersLength; i = i.uncheckedInc()) { - _setPermissionToCall(_callers[i], _targets[i], _functionSigs[i], _enables[i]); - } - } - - /// @notice Set the permission to call the function on the contract to the specified caller address - /// @param _caller The caller address, who is granted access - /// @param _target The address of the smart contract, of which access to the call is to be changed - /// @param _functionSig The function signature (selector), access to which need to be changed - /// @param _enable Whether enable or disable the permission - function setPermissionToCall( - address _caller, - address _target, - bytes4 _functionSig, - bool _enable - ) external onlyOwner { - _setPermissionToCall(_caller, _target, _functionSig, _enable); - } - - /// @dev Changes permission to call and emits the event if the permission was changed - function _setPermissionToCall(address _caller, address _target, bytes4 _functionSig, bool _enable) internal { - bool currentPermission = hasSpecialAccessToCall[_caller][_target][_functionSig]; - - if (currentPermission != _enable) { - hasSpecialAccessToCall[_caller][_target][_functionSig] = _enable; - emit UpdateCallPermission(_caller, _target, _functionSig, _enable); - } - } - - /// @dev Set deposit limit data for a token - /// @param _l1Token The address of L1 token - /// @param _depositLimitation deposit limitation is active or not - /// @param _depositCap The maximum amount that can be deposited. - function setDepositLimit(address _l1Token, bool _depositLimitation, uint256 _depositCap) external onlyOwner { - tokenDeposit[_l1Token].depositLimitation = _depositLimitation; - tokenDeposit[_l1Token].depositCap = _depositCap; - emit UpdateDepositLimit(_l1Token, _depositLimitation, _depositCap); - } - - /// @dev Get deposit limit data of a token - /// @param _l1Token The address of L1 token - function getTokenDepositLimitData(address _l1Token) external view returns (Deposit memory) { - return tokenDeposit[_l1Token]; - } -} diff --git a/ethereum/contracts/common/AllowListed.sol b/ethereum/contracts/common/AllowListed.sol deleted file mode 100644 index e889e7c1d..000000000 --- a/ethereum/contracts/common/AllowListed.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import "./interfaces/IAllowList.sol"; - -/// @author Matter Labs -/// @custom:security-contact security@matterlabs.dev -abstract contract AllowListed { - modifier senderCanCallFunction(IAllowList _allowList) { - // Preventing the stack too deep error - { - require(_allowList.canCall(msg.sender, address(this), msg.sig), "nr"); - } - _; - } -} diff --git a/ethereum/contracts/common/interfaces/IAllowList.sol b/ethereum/contracts/common/interfaces/IAllowList.sol deleted file mode 100644 index 1cd1462d5..000000000 --- a/ethereum/contracts/common/interfaces/IAllowList.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -interface IAllowList { - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /// @notice Access mode of target contract is changed - event UpdateAccessMode(address indexed target, AccessMode previousMode, AccessMode newMode); - - /// @notice Permission to call is changed - event UpdateCallPermission(address indexed caller, address indexed target, bytes4 indexed functionSig, bool status); - - /// @notice Deposit limit of a token is changed - event UpdateDepositLimit(address indexed l1Token, bool depositLimitation, uint256 depositCap); - - /// @notice Type of access to a specific contract includes three different modes - /// @param Closed No one has access to the contract - /// @param SpecialAccessOnly Any address with granted special access can interact with a contract (see `hasSpecialAccessToCall`) - /// @param Public Everyone can interact with a contract - enum AccessMode { - Closed, - SpecialAccessOnly, - Public - } - - /// @dev A struct that contains deposit limit data of a token - /// @param depositLimitation Whether any deposit limitation is placed or not - /// @param depositCap The maximum amount that can be deposited. - struct Deposit { - bool depositLimitation; - uint256 depositCap; - } - - /*////////////////////////////////////////////////////////////// - GETTERS - //////////////////////////////////////////////////////////////*/ - - function getAccessMode(address _target) external view returns (AccessMode); - - function hasSpecialAccessToCall(address _caller, address _target, bytes4 _functionSig) external view returns (bool); - - function canCall(address _caller, address _target, bytes4 _functionSig) external view returns (bool); - - function getTokenDepositLimitData(address _l1Token) external view returns (Deposit memory); - - /*////////////////////////////////////////////////////////////// - ALLOW LIST LOGIC - //////////////////////////////////////////////////////////////*/ - - function setBatchAccessMode(address[] calldata _targets, AccessMode[] calldata _accessMode) external; - - function setAccessMode(address _target, AccessMode _accessMode) external; - - function setBatchPermissionToCall( - address[] calldata _callers, - address[] calldata _targets, - bytes4[] calldata _functionSigs, - bool[] calldata _enables - ) external; - - function setPermissionToCall(address _caller, address _target, bytes4 _functionSig, bool _enable) external; - - /*////////////////////////////////////////////////////////////// - DEPOSIT LIMIT LOGIC - //////////////////////////////////////////////////////////////*/ - - function setDepositLimit(address _l1Token, bool _depositLimitation, uint256 _depositCap) external; -} diff --git a/ethereum/contracts/dev-contracts/test/TransactionValidatorTest.sol b/ethereum/contracts/dev-contracts/test/TransactionValidatorTest.sol deleted file mode 100644 index 3ec4ded29..000000000 --- a/ethereum/contracts/dev-contracts/test/TransactionValidatorTest.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import "../../zksync/libraries/TransactionValidator.sol"; -import "../../zksync/interfaces/IMailbox.sol"; - -contract TransactionValidatorTest { - function validateL1ToL2Transaction( - IMailbox.L2CanonicalTransaction memory _transaction, - uint256 _priorityTxMaxGasLimit - ) external pure { - TransactionValidator.validateL1ToL2Transaction(_transaction, abi.encode(_transaction), _priorityTxMaxGasLimit); - } - - function validateUpgradeTransaction(IMailbox.L2CanonicalTransaction memory _transaction) external pure { - TransactionValidator.validateUpgradeTransaction(_transaction); - } -} diff --git a/ethereum/scripts/allow-list-manager.ts b/ethereum/scripts/allow-list-manager.ts deleted file mode 100644 index b1962121a..000000000 --- a/ethereum/scripts/allow-list-manager.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { Command } from "commander"; -import { Interface } from "ethers/lib/utils"; -import * as hardhat from "hardhat"; -import type { AccessMode, PermissionToCall } from "./utils"; -import { getLowerCaseAddress, permissionToCallComparator, print } from "./utils"; - -// Get the interfaces for all needed contracts -const allowList = new Interface(hardhat.artifacts.readArtifactSync("IAllowList").abi); -const zkSync = new Interface(hardhat.artifacts.readArtifactSync("IZkSync").abi); -const l1ERC20Bridge = new Interface(hardhat.artifacts.readArtifactSync("L1ERC20Bridge").abi); - -const ZKSYNC_MAINNET_ADDRESS = "0x32400084c286cf3e17e7b677ea9583e60a000324"; -const L1_ERC20_BRIDGE_MAINNET_ADDRESS = "0x57891966931Eb4Bb6FB81430E6cE0A03AAbDe063"; - -const ALPHA_MAINNET_ALLOW_LIST = [ - { - target: ZKSYNC_MAINNET_ADDRESS, - functionName: "requestL2Transaction", - }, - { - target: L1_ERC20_BRIDGE_MAINNET_ADDRESS, - functionName: "deposit", - }, - { - target: L1_ERC20_BRIDGE_MAINNET_ADDRESS, - functionName: "claimFailedDeposit", - }, - { - target: L1_ERC20_BRIDGE_MAINNET_ADDRESS, - functionName: "finalizeWithdrawal", - }, -]; - -function functionSelector(functionName: string): string { - const selectors = new Array(0); - - try { - selectors.push(zkSync.getSighash(zkSync.getFunction(functionName))); - } catch { - // ignore - } - - try { - selectors.push(l1ERC20Bridge.getSighash(l1ERC20Bridge.getFunction(functionName))); - } catch { - // ignore - } - - if (selectors.length == 0) { - throw `No selector found for the ${functionName} function`; - } - - if (selectors.length > 1) { - throw `More than one selectors found for the ${functionName} function`; - } - - return selectors[0]; -} - -function setBatchPermissionToCall(parameters: Array) { - parameters.sort(permissionToCallComparator); - for (let i = 1; i < parameters.length; i++) { - if (permissionToCallComparator(parameters[i - 1], parameters[i]) === 0) { - throw new Error("Duplicates for the set batch permission to call method"); - } - } - // Extend parameters with the function selector, to check it manually - const extendedParameters = parameters.map((param) => - Object.assign(param, { functionSel: functionSelector(param.functionName) }) - ); - print("parameters", extendedParameters); - - const callers = extendedParameters.map((permissionToCall) => permissionToCall.caller); - const targets = extendedParameters.map((permissionToCall) => permissionToCall.target); - const functionSelectors = extendedParameters.map((permissionToCall) => permissionToCall.functionSel); - const enables = extendedParameters.map((permissionToCall) => permissionToCall.enable); - - const calldata = allowList.encodeFunctionData("setBatchPermissionToCall", [ - callers, - targets, - functionSelectors, - enables, - ]); - print("setBatchPermissionToCall", calldata); -} - -function setPermissionToCall(caller: string, target: string, functionName: string, enable: boolean) { - const functionSel = functionSelector(functionName); - print("parameters", { caller, target, functionName, functionSel, enable }); - - const calldata = allowList.encodeFunctionData("setPermissionToCall", [caller, target, functionSel, enable]); - print("setPermissionToCall", calldata); -} - -function setAccessMode(target: string, mode: number) { - print("parameters", { target, mode }); - - const calldata = allowList.encodeFunctionData("setAccessMode", [target, mode]); - print("setAccessMode", calldata); -} - -function setBatchAccessMode(parameters: Array) { - parameters.sort((a, b) => getLowerCaseAddress(a.target).localeCompare(getLowerCaseAddress(b.target))); - for (let i = 1; i < parameters.length; i++) { - if (getLowerCaseAddress(parameters[i - 1].target) === getLowerCaseAddress(parameters[i].target)) { - throw new Error("Duplicated targets for the set batch access mode method"); - } - } - print("parameters", parameters); - - const targets = parameters.map((publicAccess) => publicAccess.target); - const modes = parameters.map((publicAccess) => publicAccess.mode); - - const calldata = allowList.encodeFunctionData("setBatchAccessMode", [targets, modes]); - print("setBatchAccessMode", calldata); -} - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("allow-list-manager"); - - const prepareCalldataProgram = program.command("prepare-calldata"); - - prepareCalldataProgram - .command("set-permission-to-call") - .requiredOption("--caller ") - .requiredOption("--target ") - .requiredOption("--function-name ") - .requiredOption("--enable ") - .action((cmd) => { - setPermissionToCall(cmd.caller, cmd.target, cmd.functionName, cmd.enable); - }); - - prepareCalldataProgram - .command("set-batch-permission-to-call ") - .action((permissionToCall: string) => { - const parameters: Array = JSON.parse(permissionToCall); - setBatchPermissionToCall(parameters); - }); - - prepareCalldataProgram - .command("set-access-mode") - .requiredOption("--target ") - .requiredOption("--mode ") - .action((cmd) => { - setAccessMode(cmd.target, cmd.mode); - }); - - prepareCalldataProgram.command("set-batch-access-mode ").action((publicAccess: string) => { - const parameters = JSON.parse(publicAccess); - setBatchAccessMode(parameters); - }); - - const alphaMainnet = program.command("alpha-mainnet"); - - alphaMainnet.command("add ").action(async (addresses: string) => { - const parsedAddresses = JSON.parse(addresses); - const parameters: Array = new Array(0); - for (const caller of parsedAddresses) { - for (const permission of ALPHA_MAINNET_ALLOW_LIST) { - parameters.push({ caller, enable: true, ...permission }); - } - } - - setBatchPermissionToCall(parameters); - }); - - alphaMainnet.command("remove ").action(async (addresses: string) => { - const parsedAddresses = JSON.parse(addresses); - const parameters: Array = new Array(0); - for (const caller of parsedAddresses) { - for (const permission of ALPHA_MAINNET_ALLOW_LIST) { - parameters.push({ caller, enable: false, ...permission }); - } - } - - setBatchPermissionToCall(parameters); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/ethereum/scripts/initialize-l1-allow-list.ts b/ethereum/scripts/initialize-l1-allow-list.ts deleted file mode 100644 index 772885235..000000000 --- a/ethereum/scripts/initialize-l1-allow-list.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Command } from "commander"; -import { Wallet } from "ethers"; -import { Deployer } from "../src.ts/deploy"; -import * as fs from "fs"; -import * as path from "path"; -import { web3Provider } from "./utils"; - -const provider = web3Provider(); -const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant"); -const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); - -export enum AccessMode { - Closed = 0, - SpecialAccessOnly = 1, - Public = 2, -} - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("initialize-l1-allow-list"); - - program - .option("--private-key ") - .option("--nonce ") - .action(async (cmd) => { - const wallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - console.log(`Using wallet: ${wallet.address}`); - - const nonce = cmd.nonce ? parseInt(cmd.nonce) : await wallet.getTransactionCount(); - console.log(`Using nonce: ${nonce}`); - - const deployer = new Deployer({ deployWallet: wallet }); - - const allowListContract = deployer.l1AllowList(wallet); - const tx = await allowListContract.setBatchAccessMode( - [ - deployer.addresses.ZkSync.DiamondProxy, - deployer.addresses.Bridges.ERC20BridgeProxy, - deployer.addresses.Bridges.WethBridgeProxy, - ], - [AccessMode.Public, AccessMode.Public, AccessMode.Public], - { nonce } - ); - await tx.wait(); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/DepositLimit.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/DepositLimit.t.sol deleted file mode 100644 index 3bea8c2dd..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/DepositLimit.t.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {Vm} from "forge-std/Test.sol"; -import {AccessModeTest} from "./_AccessMode_Shared.t.sol"; -import {IAllowList} from "../../../../../../cache/solpp-generated-contracts/common/interfaces/IAllowList.sol"; - -contract DepositLimitTest is AccessModeTest { - address private l1token = makeAddr("l1token"); - - function test_RevertWhen_NonOwner() public { - vm.expectRevert(abi.encodePacked("Ownable: caller is not the owner")); - vm.prank(randomSigner); - allowList.setDepositLimit(l1token, true, 1000); - } - - function test_Owner() public { - vm.prank(owner); - allowList.setDepositLimit(l1token, true, 1000); - - IAllowList.Deposit memory deposit = allowList.getTokenDepositLimitData(l1token); - assertEq(deposit.depositLimitation, true, "depositLimitation should be true"); - assertEq(deposit.depositCap, 1000, "depositCap should be 1000"); - } - - function test_UnlimitedToken() public { - address unlimitedToken = makeAddr("unlimitedToken"); - - IAllowList.Deposit memory deposit = allowList.getTokenDepositLimitData(unlimitedToken); - - assertEq(deposit.depositLimitation, false, "depositLimitation should be false"); - assertEq(deposit.depositCap, 0, "depositCap should be 0"); - } - - function test_UpdateDepositLimitEvent() public { - vm.startPrank(owner); - - vm.recordLogs(); - allowList.setDepositLimit(l1token, true, 1000); - Vm.Log[] memory entries = vm.getRecordedLogs(); - - assertEq(entries.length, 1); - assertEq(entries[0].topics.length, 2); - assertEq( - entries[0].topics[0], - keccak256("UpdateDepositLimit(address,bool,uint256)"), - "received event should be correct" - ); - assertEq( - entries[0].topics[1], - bytes32(uint256(uint160(l1token))), - "received l1Token address should be correct" - ); - assertEq( - entries[0].data, - abi.encode(true, 1000), - "received depositLimitation and depositCap should be correct" - ); - } -} diff --git a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/SetAccessMode.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/SetAccessMode.t.sol deleted file mode 100644 index bc7a98220..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/SetAccessMode.t.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {AccessModeTest} from "./_AccessMode_Shared.t.sol"; -import {IAllowList} from "../../../../../../cache/solpp-generated-contracts/common/interfaces/IAllowList.sol"; - -contract SetAccessModeTest is AccessModeTest { - function test_RevertWhen_NonOwner() public { - vm.expectRevert(abi.encodePacked("Ownable: caller is not the owner")); - vm.prank(randomSigner); - allowList.setAccessMode(target, IAllowList.AccessMode.Public); - } - - function test_Owner() public { - vm.prank(owner); - allowList.setAccessMode(target, IAllowList.AccessMode.Public); - } - - function test_OwnerTwice() public { - vm.prank(owner); - allowList.setAccessMode(target, IAllowList.AccessMode.Public); - - vm.prank(owner); - allowList.setAccessMode(target, IAllowList.AccessMode.Public); - } - - function test_AccessModeBefore() public { - bool hasSpecialAccessToCall = allowList.hasSpecialAccessToCall(owner, target, functionSig); - assertEq(hasSpecialAccessToCall, false, "hasSpecialAccessToCall should be false"); - - IAllowList.AccessMode accessMode = allowList.getAccessMode(target); - bool isClosed = accessMode == IAllowList.AccessMode.Closed; - assertEq(isClosed, true, "AccessMode should be Closed"); - - bool canCall = allowList.canCall(owner, target, functionSig); - assertEq(canCall, false, "canCall should be false"); - } - - function test_AccessModeAfter() public { - vm.prank(owner); - allowList.setAccessMode(target, IAllowList.AccessMode.Public); - - bool hasSpecialAccessToCall = allowList.hasSpecialAccessToCall(owner, target, functionSig); - assertEq(hasSpecialAccessToCall, false, "hasSpecialAccessToCall should be false"); - - IAllowList.AccessMode accessMode = allowList.getAccessMode(target); - bool isPublic = accessMode == IAllowList.AccessMode.Public; - assertEq(isPublic, true, "AccessMode should be Public"); - - bool canCall = allowList.canCall(owner, target, functionSig); - assertEq(canCall, true, "canCall should be true"); - } - - function test_RemovePermission() public { - vm.prank(owner); - allowList.setAccessMode(target, IAllowList.AccessMode.Closed); - - vm.prank(owner); - allowList.setAccessMode(target, IAllowList.AccessMode.Public); - - bool hasSpecialAccessToCall = allowList.hasSpecialAccessToCall(owner, target, functionSig); - assertEq(hasSpecialAccessToCall, false, "hasSpecialAccessToCall should be false"); - - IAllowList.AccessMode accessMode = allowList.getAccessMode(target); - bool isPublic = accessMode == IAllowList.AccessMode.Public; - assertEq(isPublic, true, "AccessMode should be Public"); - - bool canCall = allowList.canCall(owner, target, functionSig); - assertEq(canCall, true, "canCall should be true"); - } -} diff --git a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/SetBatchAccessMode.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/SetBatchAccessMode.t.sol deleted file mode 100644 index 821b272e9..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/SetBatchAccessMode.t.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {AccessModeTest} from "./_AccessMode_Shared.t.sol"; -import {IAllowList} from "../../../../../../cache/solpp-generated-contracts/common/interfaces/IAllowList.sol"; - -contract SetBatchAccessModeTest is AccessModeTest { - function test_RevertWhen_NonOwner() public { - address[] memory targets = new address[](2); - targets[0] = target; - targets[1] = target; - - IAllowList.AccessMode[] memory accessModes = new IAllowList.AccessMode[](2); - accessModes[0] = IAllowList.AccessMode.Public; - accessModes[1] = IAllowList.AccessMode.Public; - - vm.expectRevert("Ownable: caller is not the owner"); - vm.prank(randomSigner); - allowList.setBatchAccessMode(targets, accessModes); - } - - function test_Owner() public { - address[] memory targets = new address[](2); - targets[0] = target; - targets[1] = target; - - IAllowList.AccessMode[] memory accessModes = new IAllowList.AccessMode[](2); - accessModes[0] = IAllowList.AccessMode.Public; - accessModes[1] = IAllowList.AccessMode.Public; - - vm.prank(owner); - allowList.setBatchAccessMode(targets, accessModes); - } - - function test_RevertWhen_ArrayLengthNotEqual() public { - address[] memory targets = new address[](1); - targets[0] = target; - - IAllowList.AccessMode[] memory accessModes = new IAllowList.AccessMode[](2); - accessModes[0] = IAllowList.AccessMode.Public; - accessModes[1] = IAllowList.AccessMode.Public; - - vm.expectRevert(abi.encodePacked("yg")); - vm.prank(owner); - allowList.setBatchAccessMode(targets, accessModes); - } -} diff --git a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/_AccessMode_Shared.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/_AccessMode_Shared.t.sol deleted file mode 100644 index 444b839c3..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/AccessMode/_AccessMode_Shared.t.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {AllowListTest} from "../_AllowList_Shared.t.sol"; - -contract AccessModeTest is AllowListTest { - address internal target = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045; - bytes4 internal functionSig = 0xdeadbeaf; -} diff --git a/ethereum/test/foundry/unit/concrete/AllowList/Permission/SetBatchPermissionToCall.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/Permission/SetBatchPermissionToCall.t.sol deleted file mode 100644 index 12211d6fd..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/Permission/SetBatchPermissionToCall.t.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {PermissionTest} from "./_Permission_Shared.t.sol"; - -contract SetBatchPermissionToCall is PermissionTest { - function test_RevertWhen_NonOwner() public { - address[] memory callers = new address[](2); - callers[0] = owner; - callers[1] = owner; - - address[] memory targets = new address[](2); - targets[0] = target; - targets[1] = target; - - bytes4[] memory functionSigs = new bytes4[](2); - functionSigs[0] = functionSig; - functionSigs[1] = functionSig; - - bool[] memory enables = new bool[](2); - enables[0] = true; - enables[1] = true; - - vm.expectRevert("Ownable: caller is not the owner"); - vm.prank(randomSigner); - allowList.setBatchPermissionToCall(callers, targets, functionSigs, enables); - } - - function test_Owner() public { - address[] memory callers = new address[](2); - callers[0] = owner; - callers[1] = owner; - - address[] memory targets = new address[](2); - targets[0] = target; - targets[1] = target; - - bytes4[] memory functionSigs = new bytes4[](2); - functionSigs[0] = functionSig; - functionSigs[1] = functionSig; - - bool[] memory enables = new bool[](2); - enables[0] = true; - enables[1] = true; - - vm.prank(owner); - allowList.setBatchPermissionToCall(callers, targets, functionSigs, enables); - } - - function test_RevertWhen_ArrayLengthNotEqual() public { - address[] memory callers = new address[](1); - callers[0] = owner; - - address[] memory targets = new address[](2); - targets[0] = target; - targets[1] = target; - - bytes4[] memory functionSigs = new bytes4[](2); - functionSigs[0] = functionSig; - functionSigs[1] = functionSig; - - bool[] memory enables = new bool[](2); - enables[0] = true; - enables[1] = true; - - vm.expectRevert(abi.encodePacked("yw")); - vm.prank(owner); - allowList.setBatchPermissionToCall(callers, targets, functionSigs, enables); - } -} diff --git a/ethereum/test/foundry/unit/concrete/AllowList/Permission/SetPermissionToCall.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/Permission/SetPermissionToCall.t.sol deleted file mode 100644 index fd46ae6a6..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/Permission/SetPermissionToCall.t.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {PermissionTest} from "./_Permission_Shared.t.sol"; -import {IAllowList} from "../../../../../../cache/solpp-generated-contracts/common/interfaces/IAllowList.sol"; - -contract SetPermissionToCallTest is PermissionTest { - function test_RevertWhen_NonOwner() public { - vm.expectRevert(abi.encodePacked("Ownable: caller is not the owner")); - vm.prank(randomSigner); - allowList.setPermissionToCall(randomSigner, target, functionSig, true); - } - - function test_Owner() public { - vm.prank(owner); - allowList.setPermissionToCall(randomSigner, target, functionSig, true); - } - - function test_OwnerTwice() public { - vm.prank(owner); - allowList.setPermissionToCall(randomSigner, target, functionSig, true); - - vm.prank(owner); - allowList.setPermissionToCall(randomSigner, target, functionSig, true); - } - - function test_PermissionBefore() public { - bool hasSpecialAccessToCall = allowList.hasSpecialAccessToCall(randomSigner, target, functionSig); - assertEq(hasSpecialAccessToCall, false, "hasSpecialAccessToCall should be false"); - - IAllowList.AccessMode accessMode = allowList.getAccessMode(target); - bool isClosed = accessMode == IAllowList.AccessMode.Closed; - assertEq(isClosed, true, "accessMode should be Closed"); - - bool canCall = allowList.canCall(randomSigner, target, functionSig); - assertEq(canCall, false, "canCall should be false"); - } - - function test_PermissionAfter() public { - vm.prank(owner); - allowList.setPermissionToCall(randomSigner, target, functionSig, true); - bool hasSpecialAccessToCall = allowList.hasSpecialAccessToCall(randomSigner, target, functionSig); - assertEq(hasSpecialAccessToCall, true, "hasSpecialAccessToCall should be true"); - - IAllowList.AccessMode accessMode = allowList.getAccessMode(target); - bool isClosed = accessMode == IAllowList.AccessMode.Closed; - assertEq(isClosed, true, "accessMode should be Closed"); - - bool canCall = allowList.canCall(randomSigner, target, functionSig); - assertEq(canCall, false, "canCall should be false"); - } - - function test_RemovePermission() public { - vm.prank(owner); - allowList.setPermissionToCall(randomSigner, target, functionSig, true); - bool hasSpecialAccessToCall = allowList.hasSpecialAccessToCall(randomSigner, target, functionSig); - assertEq(hasSpecialAccessToCall, true, "should be true"); - - vm.prank(owner); - allowList.setPermissionToCall(randomSigner, target, functionSig, false); - - hasSpecialAccessToCall = allowList.hasSpecialAccessToCall(randomSigner, target, functionSig); - assertEq(hasSpecialAccessToCall, false, "hasSpecialAccessToCall should be false"); - } -} diff --git a/ethereum/test/foundry/unit/concrete/AllowList/Permission/_Permission_Shared.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/Permission/_Permission_Shared.t.sol deleted file mode 100644 index c4bb4dc62..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/Permission/_Permission_Shared.t.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {AllowListTest} from "../_AllowList_Shared.t.sol"; - -contract PermissionTest is AllowListTest { - address internal target = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045; - bytes4 internal functionSig = 0x1626ba7e; -} diff --git a/ethereum/test/foundry/unit/concrete/AllowList/_AllowList_Shared.t.sol b/ethereum/test/foundry/unit/concrete/AllowList/_AllowList_Shared.t.sol deleted file mode 100644 index a7778617b..000000000 --- a/ethereum/test/foundry/unit/concrete/AllowList/_AllowList_Shared.t.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {AllowList} from "../../../../../cache/solpp-generated-contracts/common/AllowList.sol"; - -contract AllowListTest is Test { - AllowList internal allowList; - address internal owner = makeAddr("owner"); - address internal randomSigner = makeAddr("randomSigner"); - - function setUp() public { - allowList = new AllowList(owner); - } -} diff --git a/ethereum/test/unit_tests/merkle_test.spec.ts b/ethereum/test/unit_tests/merkle_test.spec.ts deleted file mode 100644 index 9ba239317..000000000 --- a/ethereum/test/unit_tests/merkle_test.spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { expect } from "chai"; -import * as hardhat from "hardhat"; -import type { MerkleTest } from "../../typechain"; -import { MerkleTestFactory } from "../../typechain"; -import { MerkleTree } from "merkletreejs"; -import { getCallRevertReason } from "./utils"; -import * as ethers from "ethers"; - -describe("Merkle lib tests", function () { - let merkleTest: MerkleTest; - - before(async () => { - const contractFactory = await hardhat.ethers.getContractFactory("MerkleTest"); - const contract = await contractFactory.deploy(); - merkleTest = MerkleTestFactory.connect(contract.address, contract.signer); - }); - - describe("should calculate root correctly", function () { - let elements; - let merkleTree; - - before(async () => { - elements = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - .split("") - .map((val) => ethers.utils.toUtf8Bytes(val)); - merkleTree = new MerkleTree(elements, ethers.utils.keccak256, { hashLeaves: true }); - }); - - it("first element", async () => { - const index = 0; - const leaf = ethers.utils.keccak256(elements[index]); - const proof = merkleTree.getHexProof(leaf, index); - - const rootFromContract = await merkleTest.calculateRoot(proof, index, leaf); - expect(rootFromContract).to.equal(merkleTree.getHexRoot()); - }); - - it("middle element", async () => { - const index = Math.ceil(elements.length / 2); - const leaf = ethers.utils.keccak256(elements[index]); - const proof = merkleTree.getHexProof(leaf, index); - - const rootFromContract = await merkleTest.calculateRoot(proof, index, leaf); - expect(rootFromContract).to.equal(merkleTree.getHexRoot()); - }); - - it("last element", async () => { - const index = elements.length - 1; - const leaf = ethers.utils.keccak256(elements[index]); - const proof = merkleTree.getHexProof(leaf, index); - - const rootFromContract = await merkleTest.calculateRoot(proof, index, leaf); - expect(rootFromContract).to.equal(merkleTree.getHexRoot()); - }); - }); - - it("should fail trying calculate root with empty path", async () => { - const revertReason = await getCallRevertReason(merkleTest.calculateRoot([], 0, ethers.constants.HashZero)); - expect(revertReason).equal("xc"); - }); - - it("should fail trying calculate root with too big leaf index", async () => { - const bigIndex = ethers.BigNumber.from(2).pow(255); - const revertReason = await getCallRevertReason( - merkleTest.calculateRoot([ethers.constants.HashZero], bigIndex, ethers.constants.HashZero) - ); - expect(revertReason).equal("px"); - }); -}); diff --git a/ethereum/test/unit_tests/priority_queue_test.spec.ts b/ethereum/test/unit_tests/priority_queue_test.spec.ts deleted file mode 100644 index a59c1e2f1..000000000 --- a/ethereum/test/unit_tests/priority_queue_test.spec.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { expect } from "chai"; -import * as hardhat from "hardhat"; -import { ethers } from "hardhat"; -import type { PriorityQueueTest } from "../../typechain"; -import { PriorityQueueTestFactory } from "../../typechain"; -import { getCallRevertReason } from "./utils"; - -describe("Priority queue tests", function () { - let priorityQueueTest: PriorityQueueTest; - const queue = []; - - before(async () => { - const contractFactory = await hardhat.ethers.getContractFactory("PriorityQueueTest"); - const contract = await contractFactory.deploy(); - priorityQueueTest = PriorityQueueTestFactory.connect(contract.address, contract.signer); - }); - - describe("on empty queue", function () { - it("getSize", async () => { - const size = await priorityQueueTest.getSize(); - expect(size).equal(0); - }); - - it("getFirstUnprocessedPriorityTx", async () => { - const firstUnprocessedTx = await priorityQueueTest.getFirstUnprocessedPriorityTx(); - expect(firstUnprocessedTx).equal(0); - }); - - it("getTotalPriorityTxs", async () => { - const totalPriorityTxs = await priorityQueueTest.getTotalPriorityTxs(); - expect(totalPriorityTxs).equal(0); - }); - - it("isEmpty", async () => { - const isEmpty = await priorityQueueTest.isEmpty(); - expect(isEmpty).equal(true); - }); - - it("failed to get front", async () => { - const revertReason = await getCallRevertReason(priorityQueueTest.front()); - expect(revertReason).equal("D"); - }); - - it("failed to pop", async () => { - const revertReason = await getCallRevertReason(priorityQueueTest.popFront()); - expect(revertReason).equal("s"); - }); - }); - - describe("push operations", function () { - const NUMBER_OPERATIONS = 10; - - before(async () => { - for (let i = 0; i < NUMBER_OPERATIONS; ++i) { - const dummyOp = { canonicalTxHash: ethers.constants.HashZero, expirationTimestamp: i, layer2Tip: i }; - queue.push(dummyOp); - await priorityQueueTest.pushBack(dummyOp); - } - }); - - it("front", async () => { - const frontElement = await priorityQueueTest.front(); - - expect(frontElement.canonicalTxHash).equal(queue[0].canonicalTxHash); - expect(frontElement.expirationTimestamp).equal(queue[0].expirationTimestamp); - expect(frontElement.layer2Tip).equal(queue[0].layer2Tip); - }); - - it("getSize", async () => { - const size = await priorityQueueTest.getSize(); - expect(size).equal(queue.length); - }); - - it("getFirstUnprocessedPriorityTx", async () => { - const firstUnprocessedTx = await priorityQueueTest.getFirstUnprocessedPriorityTx(); - expect(firstUnprocessedTx).equal(0); - }); - - it("getTotalPriorityTxs", async () => { - const totalPriorityTxs = await priorityQueueTest.getTotalPriorityTxs(); - expect(totalPriorityTxs).equal(queue.length); - }); - - it("isEmpty", async () => { - const isEmpty = await priorityQueueTest.isEmpty(); - expect(isEmpty).equal(false); - }); - }); - - describe("pop operations", function () { - const NUMBER_OPERATIONS = 4; - - before(async () => { - for (let i = 0; i < NUMBER_OPERATIONS; ++i) { - const frontElement = await priorityQueueTest.front(); - expect(frontElement.canonicalTxHash).equal(queue[0].canonicalTxHash); - expect(frontElement.expirationTimestamp).equal(queue[0].expirationTimestamp); - expect(frontElement.layer2Tip).equal(queue[0].layer2Tip); - - await priorityQueueTest.popFront(); - queue.shift(); - } - }); - - it("front", async () => { - const frontElement = await priorityQueueTest.front(); - - expect(frontElement.canonicalTxHash).equal(queue[0].canonicalTxHash); - expect(frontElement.expirationTimestamp).equal(queue[0].expirationTimestamp); - expect(frontElement.layer2Tip).equal(queue[0].layer2Tip); - }); - - it("getSize", async () => { - const size = await priorityQueueTest.getSize(); - expect(size).equal(queue.length); - }); - - it("getFirstUnprocessedPriorityTx", async () => { - const firstUnprocessedTx = await priorityQueueTest.getFirstUnprocessedPriorityTx(); - expect(firstUnprocessedTx).equal(NUMBER_OPERATIONS); - }); - - it("getTotalPriorityTxs", async () => { - const totalPriorityTxs = await priorityQueueTest.getTotalPriorityTxs(); - expect(totalPriorityTxs).equal(queue.length + NUMBER_OPERATIONS); - }); - - it("isEmpty", async () => { - const isEmpty = await priorityQueueTest.isEmpty(); - expect(isEmpty).equal(false); - }); - }); -}); diff --git a/ethereum/test/unit_tests/transaction_validator_test.spec.ts b/ethereum/test/unit_tests/transaction_validator_test.spec.ts deleted file mode 100644 index a8683c368..000000000 --- a/ethereum/test/unit_tests/transaction_validator_test.spec.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { expect } from "chai"; -import * as hardhat from "hardhat"; -import type { TransactionValidatorTest } from "../../typechain"; -import { TransactionValidatorTestFactory } from "../../typechain"; -import { getCallRevertReason } from "./utils"; -import * as ethers from "ethers"; - -describe("TransactionValidator tests", function () { - let tester: TransactionValidatorTest; - before(async () => { - const testerFactory = await hardhat.ethers.getContractFactory("TransactionValidatorTest"); - const testerContract = await testerFactory.deploy(); - tester = TransactionValidatorTestFactory.connect(testerContract.address, testerContract.signer); - }); - - describe("validateL1ToL2Transaction", function () { - it("Should not revert when all parameters are valid", async () => { - await tester.validateL1ToL2Transaction(createTestTransaction({}), 500000); - }); - - it("Should revert when provided gas limit doesnt cover transaction overhead", async () => { - const result = await getCallRevertReason( - tester.validateL1ToL2Transaction( - createTestTransaction({ - gasLimit: 0, - }), - 500000 - ) - ); - expect(result).equal("my"); - }); - - it("Should revert when needed gas is higher than the max", async () => { - const result = await getCallRevertReason(tester.validateL1ToL2Transaction(createTestTransaction({}), 0)); - expect(result).equal("ui"); - }); - - it("Should revert when transaction can output more pubdata than processable", async () => { - const result = await getCallRevertReason( - tester.validateL1ToL2Transaction( - createTestTransaction({ - gasPerPubdataByteLimit: 1, - }), - 500000 - ) - ); - expect(result).equal("uk"); - }); - - it("Should revert when transaction gas doesnt pay the minimum costs", async () => { - const result = await getCallRevertReason( - tester.validateL1ToL2Transaction( - createTestTransaction({ - gasLimit: 200000, - }), - 500000 - ) - ); - expect(result).equal("up"); - }); - }); - - describe("validateUpgradeTransaction", function () { - it("Should not revert when all parameters are valid", async () => { - await tester.validateUpgradeTransaction(createTestTransaction({})); - }); - - it("Should revert when from is too large", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - from: ethers.BigNumber.from(2).pow(16), - }) - ) - ); - expect(result).equal("ua"); - }); - - it("Should revert when to is too large", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - to: ethers.BigNumber.from(2).pow(161), - }) - ) - ); - expect(result).equal("ub"); - }); - - it("Should revert when paymaster is non-zero", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - paymaster: 1, - }) - ) - ); - expect(result).equal("uc"); - }); - - it("Should revert when value is non-zero", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - value: 1, - }) - ) - ); - expect(result).equal("ud"); - }); - - it("Should revert when reserved[0] is non-zero", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - reserved: [1, 0, 0, 0], - }) - ) - ); - expect(result).equal("ue"); - }); - - it("Should revert when reserved[1] is too large", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - reserved: [0, ethers.BigNumber.from(2).pow(161), 0, 0], - }) - ) - ); - expect(result).equal("uf"); - }); - - it("Should revert when reserved[2] is non-zero", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - reserved: [0, 0, 1, 0], - }) - ) - ); - expect(result).equal("ug"); - }); - - it("Should revert when reserved[3] is non-zero", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - reserved: [0, 0, 0, 1], - }) - ) - ); - expect(result).equal("uo"); - }); - - it("Should revert when signature has non-zero length", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - signature: "0xaa", - }) - ) - ); - expect(result).equal("uh"); - }); - - it("Should revert when paymaster input has non-zero length", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - paymasterInput: "0xaa", - }) - ) - ); - expect(result).equal("ul"); - }); - - it("Should revert when reserved dynamic field has non-zero length", async () => { - const result = await getCallRevertReason( - tester.validateUpgradeTransaction( - createTestTransaction({ - reservedDynamic: "0xaa", - }) - ) - ); - expect(result).equal("um"); - }); - }); -}); - -function createTestTransaction(overrides) { - return Object.assign( - { - txType: 0, - from: ethers.BigNumber.from(2).pow(16).sub(1), - to: 0, - gasLimit: 500000, - gasPerPubdataByteLimit: 800, - maxFeePerGas: 0, - maxPriorityFeePerGas: 0, - paymaster: 0, - nonce: 0, - value: 0, - reserved: [0, 0, 0, 0], - data: "0x", - signature: "0x", - factoryDeps: [], - paymasterInput: "0x", - reservedDynamic: "0x", - }, - overrides - ); -} diff --git a/ethereum/test/unit_tests/verifier.spec.ts b/ethereum/test/unit_tests/verifier.spec.ts deleted file mode 100644 index 437c168b9..000000000 --- a/ethereum/test/unit_tests/verifier.spec.ts +++ /dev/null @@ -1,397 +0,0 @@ -import * as hardhat from "hardhat"; -import { expect } from "chai"; -import type { VerifierTest, VerifierRecursiveTest } from "../../typechain"; -import { VerifierTestFactory } from "../../typechain"; -import { getCallRevertReason } from "./utils"; -import { ethers } from "hardhat"; - -describe("Verifier test", function () { - const Q_MOD = "21888242871839275222246405745257275088696311157297823662689037894645226208583"; - const R_MOD = "21888242871839275222246405745257275088548364400416034343698204186575808495617"; - - const PROOF = { - publicInputs: ["0xa3dd954bb76c1474c1a04f04870cc75bcaf66ec23c0303c87fb119f9"], - serializedProof: [ - "0x162e0e35310fa1265df0051490fad590e875a98b4e7781ce1bb2698887e24070", - "0x1a3645718b688a382a00b99059f9488daf624d04ceb39b5553f0a1a0d508dde6", - "0x44df31be22763cde0700cc784f70758b944096a11c9b32bfb4f559d9b6a9567", - "0x2efae700419dd3fa0bebf5404efef2f3b5f8f2288c595ec219a05607e9971c9", - "0x223e7327348fd30effc617ee9fa7e28117869f149719cf93c20788cb78adc291", - "0x99f67d073880787c73d54bc2509c1611ac6f48fbe3b5214b4dc2f3cb3a572c0", - "0x17365bde1bbcd62561764ddd8b2d562edbe1c07519cd23f03831b694c6665a2d", - "0x2f321ac8e18ab998f8fe370f3b5114598881798ccc6eac24d7f4161c15fdabb3", - "0x2f6b4b0f4973f2f6e2fa5ecd34602b20b56f0e4fb551b011af96e555fdc1197d", - "0xb8d070fec07e8467425605015acba755f54db7f566c6704818408d927419d80", - "0x103185cff27eef6e8090373749a8065129fcc93482bd6ea4db1808725b6da2e", - "0x29b35d35c22deda2ac9dd56a9f6a145871b1b6557e165296f804297160d5f98b", - "0x240bb4b0b7e30e71e8af2d908e72bf47b6496aab1e1f7cb32f2604d79f76cff8", - "0x1cd2156a0f0c1944a8a3359618ff978b27eb42075c667960817be624ce161489", - "0xbd0b75112591ab1b4a6a3e03fb76368419b78e4b95ee773b8ef5e7848695cf7", - "0xcd1da7fcfc27d2d9e9743e80951694995b162298d4109428fcf1c9a90f24905", - "0x2672327da3fdec6c58e8a0d33ca94e059da0787e9221a2a0ac412692cc962aac", - "0x50e88db23f7582691a0fb7e5c95dd713e54188833fe1d241e3e32a98dfeb0f0", - "0x8dc78ede51774238b0984b02ac7fcf8b0a8dfcb6ca733b90c6b44aac4551057", - "0x2a3167374e2d54e47ce865ef222346adf7a27d4174820a637cf656899238387", - "0x2f161fddcebb9ed8740c14d3a782efcf6f0ad069371194f87bcc04f9e9baf2ee", - "0x25dcf81d1721eab45e86ccfee579eaa4e54a4a80a19edf784f24cc1ee831e58a", - "0x1e483708e664ced677568d93b3b4f505e9d2968f802e04b31873f7d8f635fb0f", - "0x2bf6cdf920d353ba8bda932b72bf6ff6a93aa831274a5dc3ea6ea647a446d18e", - "0x2aa406a77d9143221165e066adfcc9281b9c90afdcee4336eda87f85d2bfe5b", - "0x26fc05b152609664e624a233e52e12252a0cae9d2a86a36717300063faca4b4b", - "0x24579fb180a63e5594644f4726c5af6d091aee4ee64c2c2a37d98f646a9c8d9d", - "0xb34ff9cbae3a9afe40e80a46e7d1419380e210a0e9595f61eb3a300aaef9f34", - "0x2ee89372d00fd0e32a46d513f7a80a1ae64302f33bc4b100384327a443c0193c", - "0x2b0e285154aef9e8af0777190947379df37da05cf342897bf1de1bc40e497893", - "0x158b022dd94b2c5c44994a5be28b2f570f1187277430ed9307517fa0c830d432", - "0x1d1ea6f83308f30e544948e221d6b313367eccfe54ec05dfa757f023b5758f3d", - "0x1a08a4549273627eadafe47379be8e997306f5b9567618b38c93a0d58eb6c54c", - "0xf434e5d987974afdd7f45a0f84fb800ecbbcdf2eeb302e415371e1d08ba4ad7", - "0x168b5b6d46176887125f13423384b8e8dd4fd947aac832d8d15b87865580b5fb", - "0x166cd223e74511332e2df4e7ad7a82c3871ed0305a5708521702c5e62e11a30b", - "0x10f0979b9797e30f8fe15539518c7f4dfc98c7acb1490da60088b6ff908a4876", - "0x20e08df88bbafc9a810fa8e2324c36b5513134477207763849ed4a0b6bd9639", - "0x1e977a84137396a3cfb17565ecfb5b60dffb242c7aab4afecaa45ebd2c83e0a3", - "0x19f3f9b6c6868a0e2a7453ff8949323715817869f8a25075308aa34a50c1ca3c", - "0x248b030bbfab25516cca23e7937d4b3b46967292ef6dfd3df25fcfe289d53fac", - "0x26bee4a0a5c8b76caa6b73172fa7760bd634c28d2c2384335b74f5d18e3933f4", - "0x106719993b9dacbe46b17f4e896c0c9c116d226c50afe2256dca1e81cd510b5c", - "0x19b5748fd961f755dd3c713d09014bd12adbb739fa1d2160067a312780a146a2", - ], - recursiveAggregationInput: [], - }; - let verifier: VerifierTest; - - before(async function () { - const verifierFactory = await hardhat.ethers.getContractFactory("VerifierTest"); - const verifierContract = await verifierFactory.deploy(); - verifier = VerifierTestFactory.connect(verifierContract.address, verifierContract.signer); - }); - - it("Should verify proof", async () => { - // Call the verifier directly (though the call, not static call) to add the save the consumed gas into the statistic. - const calldata = verifier.interface.encodeFunctionData("verify", [ - PROOF.publicInputs, - PROOF.serializedProof, - PROOF.recursiveAggregationInput, - ]); - await verifier.fallback({ data: calldata }); - - // Check that proof is verified - const result = await verifier.verify(PROOF.publicInputs, PROOF.serializedProof, PROOF.recursiveAggregationInput); - expect(result, "proof verification failed").true; - }); - - describe("Should verify valid proof with fields values in non standard format", function () { - it("Public input with dirty bits over Fr mask", async () => { - const validProof = JSON.parse(JSON.stringify(PROOF)); - // Fill dirty bits - validProof.publicInputs[0] = ethers.BigNumber.from(validProof.publicInputs[0]) - .add("0xe000000000000000000000000000000000000000000000000000000000000000") - .toHexString(); - const result = await verifier.verify( - validProof.publicInputs, - validProof.serializedProof, - validProof.recursiveAggregationInput - ); - expect(result, "proof verification failed").true; - }); - - it("Elliptic curve points over modulo", async () => { - const validProof = JSON.parse(JSON.stringify(PROOF)); - // Add modulo to points - validProof.serializedProof[0] = ethers.BigNumber.from(validProof.serializedProof[0]).add(Q_MOD); - validProof.serializedProof[1] = ethers.BigNumber.from(validProof.serializedProof[1]).add(Q_MOD).add(Q_MOD); - const result = await verifier.verify( - validProof.publicInputs, - validProof.serializedProof, - validProof.recursiveAggregationInput - ); - expect(result, "proof verification failed").true; - }); - - it("Fr over modulo", async () => { - const validProof = JSON.parse(JSON.stringify(PROOF)); - // Add modulo to number - validProof.serializedProof[22] = ethers.BigNumber.from(validProof.serializedProof[22]).add(R_MOD); - const result = await verifier.verify( - validProof.publicInputs, - validProof.serializedProof, - validProof.recursiveAggregationInput - ); - expect(result, "proof verification failed").true; - }); - }); - - describe("Should revert on invalid input", function () { - it("More than 1 public inputs", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Add one more public input to proof - invalidProof.publicInputs.push(invalidProof.publicInputs[0]); - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Empty public inputs", async () => { - const revertReason = await getCallRevertReason( - verifier.verify([], PROOF.serializedProof, PROOF.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("More than 44 words for proof", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Add one more "serialized proof" input - invalidProof.serializedProof.push(invalidProof.serializedProof[0]); - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Empty serialized proof", async () => { - const revertReason = await getCallRevertReason( - verifier.verify(PROOF.publicInputs, [], PROOF.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Not empty recursive aggregation input", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Add one more "recursive aggregation input" value - invalidProof.recursiveAggregationInput.push(invalidProof.publicInputs[0]); - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Elliptic curve point at infinity", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Change first point to point at infinity (encode as (0, 0) on EVM) - invalidProof.serializedProof[0] = ethers.constants.HashZero; - invalidProof.serializedProof[1] = ethers.constants.HashZero; - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - }); - - it("Should failed with invalid public input", async () => { - const revertReason = await getCallRevertReason( - verifier.verify([ethers.constants.HashZero], PROOF.serializedProof, PROOF.recursiveAggregationInput) - ); - expect(revertReason).equal("invalid quotient evaluation"); - }); - - it("Should return correct Verification key hash", async () => { - const vksHash = await verifier.verificationKeyHash(); - expect(vksHash).equal("0x6625fa96781746787b58306d414b1e25bd706d37d883a9b3acf57b2bd5e0de52"); - }); -}); - -describe("Verifier with recursive part test", function () { - const Q_MOD = "21888242871839275222246405745257275088696311157297823662689037894645226208583"; - const R_MOD = "21888242871839275222246405745257275088548364400416034343698204186575808495617"; - - const PROOF = { - publicInputs: ["0xa3dd954bb76c1474c1a04f04870cc75bcaf66ec23c0303c87fb119f9"], - serializedProof: [ - "0x162e0e35310fa1265df0051490fad590e875a98b4e7781ce1bb2698887e24070", - "0x1a3645718b688a382a00b99059f9488daf624d04ceb39b5553f0a1a0d508dde6", - "0x44df31be22763cde0700cc784f70758b944096a11c9b32bfb4f559d9b6a9567", - "0x2efae700419dd3fa0bebf5404efef2f3b5f8f2288c595ec219a05607e9971c9", - "0x223e7327348fd30effc617ee9fa7e28117869f149719cf93c20788cb78adc291", - "0x99f67d073880787c73d54bc2509c1611ac6f48fbe3b5214b4dc2f3cb3a572c0", - "0x17365bde1bbcd62561764ddd8b2d562edbe1c07519cd23f03831b694c6665a2d", - "0x2f321ac8e18ab998f8fe370f3b5114598881798ccc6eac24d7f4161c15fdabb3", - "0x2f6b4b0f4973f2f6e2fa5ecd34602b20b56f0e4fb551b011af96e555fdc1197d", - "0xb8d070fec07e8467425605015acba755f54db7f566c6704818408d927419d80", - "0x103185cff27eef6e8090373749a8065129fcc93482bd6ea4db1808725b6da2e", - "0x29b35d35c22deda2ac9dd56a9f6a145871b1b6557e165296f804297160d5f98b", - "0x240bb4b0b7e30e71e8af2d908e72bf47b6496aab1e1f7cb32f2604d79f76cff8", - "0x1cd2156a0f0c1944a8a3359618ff978b27eb42075c667960817be624ce161489", - "0xbd0b75112591ab1b4a6a3e03fb76368419b78e4b95ee773b8ef5e7848695cf7", - "0xcd1da7fcfc27d2d9e9743e80951694995b162298d4109428fcf1c9a90f24905", - "0x2672327da3fdec6c58e8a0d33ca94e059da0787e9221a2a0ac412692cc962aac", - "0x50e88db23f7582691a0fb7e5c95dd713e54188833fe1d241e3e32a98dfeb0f0", - "0x8dc78ede51774238b0984b02ac7fcf8b0a8dfcb6ca733b90c6b44aac4551057", - "0x2a3167374e2d54e47ce865ef222346adf7a27d4174820a637cf656899238387", - "0x2f161fddcebb9ed8740c14d3a782efcf6f0ad069371194f87bcc04f9e9baf2ee", - "0x25dcf81d1721eab45e86ccfee579eaa4e54a4a80a19edf784f24cc1ee831e58a", - "0x1e483708e664ced677568d93b3b4f505e9d2968f802e04b31873f7d8f635fb0f", - "0x2bf6cdf920d353ba8bda932b72bf6ff6a93aa831274a5dc3ea6ea647a446d18e", - "0x2aa406a77d9143221165e066adfcc9281b9c90afdcee4336eda87f85d2bfe5b", - "0x26fc05b152609664e624a233e52e12252a0cae9d2a86a36717300063faca4b4b", - "0x24579fb180a63e5594644f4726c5af6d091aee4ee64c2c2a37d98f646a9c8d9d", - "0xb34ff9cbae3a9afe40e80a46e7d1419380e210a0e9595f61eb3a300aaef9f34", - "0x2ee89372d00fd0e32a46d513f7a80a1ae64302f33bc4b100384327a443c0193c", - "0x2b0e285154aef9e8af0777190947379df37da05cf342897bf1de1bc40e497893", - "0x158b022dd94b2c5c44994a5be28b2f570f1187277430ed9307517fa0c830d432", - "0x1d1ea6f83308f30e544948e221d6b313367eccfe54ec05dfa757f023b5758f3d", - "0x1a08a4549273627eadafe47379be8e997306f5b9567618b38c93a0d58eb6c54c", - "0xf434e5d987974afdd7f45a0f84fb800ecbbcdf2eeb302e415371e1d08ba4ad7", - "0x168b5b6d46176887125f13423384b8e8dd4fd947aac832d8d15b87865580b5fb", - "0x166cd223e74511332e2df4e7ad7a82c3871ed0305a5708521702c5e62e11a30b", - "0x10f0979b9797e30f8fe15539518c7f4dfc98c7acb1490da60088b6ff908a4876", - "0x20e08df88bbafc9a810fa8e2324c36b5513134477207763849ed4a0b6bd9639", - "0x1e977a84137396a3cfb17565ecfb5b60dffb242c7aab4afecaa45ebd2c83e0a3", - "0x19f3f9b6c6868a0e2a7453ff8949323715817869f8a25075308aa34a50c1ca3c", - "0x248b030bbfab25516cca23e7937d4b3b46967292ef6dfd3df25fcfe289d53fac", - "0x26bee4a0a5c8b76caa6b73172fa7760bd634c28d2c2384335b74f5d18e3933f4", - "0x106719993b9dacbe46b17f4e896c0c9c116d226c50afe2256dca1e81cd510b5c", - "0x19b5748fd961f755dd3c713d09014bd12adbb739fa1d2160067a312780a146a2", - ], - recursiveAggregationInput: [ - "0x04fdf01a2faedb9e3a620bc1cd8ceb4b0adac04631bdfa9e7e9fc15e35693cc0", - "0x1419728b438cc9afa63ab4861753e0798e29e08aac0da17b2c7617b994626ca2", - "0x23ca418458f6bdc30dfdbc13b80c604f8864619582eb247d09c8e4703232897b", - "0x0713c1371914ac18d7dced467a8a60eeca0f3d80a2cbd5dcc75abb6cbab39f39", - ], - }; - let verifier: VerifierRecursiveTest; - - before(async function () { - const verifierFactory = await hardhat.ethers.getContractFactory("VerifierRecursiveTest"); - const verifierContract = await verifierFactory.deploy(); - verifier = VerifierTestFactory.connect(verifierContract.address, verifierContract.signer); - }); - - it("Should verify proof", async () => { - // Call the verifier directly (though the call, not static call) to add the save the consumed gas into the statistic. - const calldata = verifier.interface.encodeFunctionData("verify", [ - PROOF.publicInputs, - PROOF.serializedProof, - PROOF.recursiveAggregationInput, - ]); - await verifier.fallback({ data: calldata }); - - // Check that proof is verified - const result = await verifier.verify(PROOF.publicInputs, PROOF.serializedProof, PROOF.recursiveAggregationInput); - expect(result, "proof verification failed").true; - }); - - describe("Should verify valid proof with fields values in non standard format", function () { - it("Public input with dirty bits over Fr mask", async () => { - const validProof = JSON.parse(JSON.stringify(PROOF)); - // Fill dirty bits - validProof.publicInputs[0] = ethers.BigNumber.from(validProof.publicInputs[0]) - .add("0xe000000000000000000000000000000000000000000000000000000000000000") - .toHexString(); - const result = await verifier.verify( - validProof.publicInputs, - validProof.serializedProof, - validProof.recursiveAggregationInput - ); - expect(result, "proof verification failed").true; - }); - - it("Elliptic curve points over modulo", async () => { - const validProof = JSON.parse(JSON.stringify(PROOF)); - // Add modulo to points - validProof.serializedProof[0] = ethers.BigNumber.from(validProof.serializedProof[0]).add(Q_MOD); - validProof.serializedProof[1] = ethers.BigNumber.from(validProof.serializedProof[1]).add(Q_MOD).add(Q_MOD); - const result = await verifier.verify( - validProof.publicInputs, - validProof.serializedProof, - validProof.recursiveAggregationInput - ); - expect(result, "proof verification failed").true; - }); - - it("Fr over modulo", async () => { - const validProof = JSON.parse(JSON.stringify(PROOF)); - // Add modulo to number - validProof.serializedProof[22] = ethers.BigNumber.from(validProof.serializedProof[22]).add(R_MOD); - const result = await verifier.verify( - validProof.publicInputs, - validProof.serializedProof, - validProof.recursiveAggregationInput - ); - expect(result, "proof verification failed").true; - }); - }); - - describe("Should revert on invalid input", function () { - it("More than 1 public inputs", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Add one more public input to proof - invalidProof.publicInputs.push(invalidProof.publicInputs[0]); - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Empty public inputs", async () => { - const revertReason = await getCallRevertReason( - verifier.verify([], PROOF.serializedProof, PROOF.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("More than 44 words for proof", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Add one more "serialized proof" input - invalidProof.serializedProof.push(invalidProof.serializedProof[0]); - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Empty serialized proof", async () => { - const revertReason = await getCallRevertReason( - verifier.verify(PROOF.publicInputs, [], PROOF.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("More than 4 words for recursive aggregation input", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Add one more "recursive aggregation input" value - invalidProof.recursiveAggregationInput.push(invalidProof.recursiveAggregationInput[0]); - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Empty recursive aggregation input", async () => { - const revertReason = await getCallRevertReason(verifier.verify(PROOF.publicInputs, PROOF.serializedProof, [])); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - - it("Elliptic curve point at infinity", async () => { - const invalidProof = JSON.parse(JSON.stringify(PROOF)); - // Change first point to point at infinity (encode as (0, 0) on EVM) - invalidProof.serializedProof[0] = ethers.constants.HashZero; - invalidProof.serializedProof[1] = ethers.constants.HashZero; - const revertReason = await getCallRevertReason( - verifier.verify(invalidProof.publicInputs, invalidProof.serializedProof, invalidProof.recursiveAggregationInput) - ); - expect(revertReason).equal("loadProof: Proof is invalid"); - }); - }); - - it("Should failed with invalid public input", async () => { - const revertReason = await getCallRevertReason( - verifier.verify([ethers.constants.HashZero], PROOF.serializedProof, PROOF.recursiveAggregationInput) - ); - expect(revertReason).equal("invalid quotient evaluation"); - }); - - it("Should failed with invalid recursive aggregative input", async () => { - const revertReason = await getCallRevertReason( - verifier.verify(PROOF.publicInputs, PROOF.serializedProof, [1, 2, 1, 2]) - ); - expect(revertReason).equal("finalPairing: pairing failure"); - }); - - it("Should return correct Verification key hash", async () => { - const vksHash = await verifier.verificationKeyHash(); - expect(vksHash).equal("0x88b3ddc4ed85974c7e14297dcad4097169440305c05fdb6441ca8dfd77cd7fa7"); - }); -}); diff --git a/ethereum/.env b/l1-contracts/.env similarity index 100% rename from ethereum/.env rename to l1-contracts/.env diff --git a/ethereum/contracts/bridge/L1ERC20Bridge.sol b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol similarity index 90% rename from ethereum/contracts/bridge/L1ERC20Bridge.sol rename to l1-contracts/contracts/bridge/L1ERC20Bridge.sol index e9297480b..33ef7ccd4 100644 --- a/ethereum/contracts/bridge/L1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol @@ -13,8 +13,6 @@ import "./interfaces/IL2ERC20Bridge.sol"; import "./libraries/BridgeInitializationHelper.sol"; import "../zksync/interfaces/IZkSync.sol"; -import "../common/interfaces/IAllowList.sol"; -import "../common/AllowListed.sol"; import "../common/libraries/UnsafeBytes.sol"; import "../common/libraries/L2ContractHelper.sol"; import "../common/ReentrancyGuard.sol"; @@ -25,12 +23,9 @@ import "../vendor/AddressAliasHelper.sol"; /// @notice Smart contract that allows depositing ERC20 tokens from Ethereum to zkSync Era /// @dev It is standard implementation of ERC20 Bridge that can be used as a reference /// for any other custom token bridges. -contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGuard { +contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard { using SafeERC20 for IERC20; - /// @dev The smart contract that manages the list with permission to call contract functions - IAllowList internal immutable allowList; - /// @dev zkSync smart contract that is used to operate with L2 via asynchronous L2 <-> L1 communication IZkSync internal immutable zkSync; @@ -62,9 +57,8 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua /// @dev Contract is expected to be used as proxy implementation. /// @dev Initialize the implementation to prevent Parity hack. - constructor(IZkSync _zkSync, IAllowList _allowList) reentrancyGuardInitializer { + constructor(IZkSync _zkSync) reentrancyGuardInitializer { zkSync = _zkSync; - allowList = _allowList; } /// @dev Initializes a contract bridge for later use. Expected to be used in the proxy @@ -142,8 +136,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua /// @param _l2TxGasLimit The L2 gas limit to be used in the corresponding L2 transaction /// @param _l2TxGasPerPubdataByte The gasPerPubdataByteLimit to be used in the corresponding L2 transaction /// @return l2TxHash The L2 transaction hash of deposit finalization - /// NOTE: the function doesn't use `nonreentrant` and `senderCanCallFunction` modifiers, because the inner - /// method does. + /// NOTE: the function doesn't use `nonreentrant` modifier, because the inner method does. function deposit( address _l2Receiver, address _l1Token, @@ -183,12 +176,10 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte, address _refundRecipient - ) public payable nonReentrant senderCanCallFunction(allowList) returns (bytes32 l2TxHash) { + ) public payable nonReentrant returns (bytes32 l2TxHash) { require(_amount != 0, "2T"); // empty deposit amount uint256 amount = _depositFunds(msg.sender, IERC20(_l1Token), _amount); require(amount == _amount, "1T"); // The token has non-standard transfer logic - // verify the deposit amount is allowed - _verifyDepositLimit(_l1Token, msg.sender, _amount, false); bytes memory l2TxCalldata = _getDepositL2Calldata(msg.sender, _l2Receiver, _l1Token, amount); // If the refund recipient is not specified, the refund will be sent to the sender of the transaction. @@ -264,7 +255,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof - ) external nonReentrant senderCanCallFunction(allowList) { + ) external nonReentrant { bool proofValid = zkSync.proveL1ToL2TransactionStatus( _l2TxHash, _l2BatchNumber, @@ -278,9 +269,6 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua uint256 amount = depositAmount[_depositSender][_l1Token][_l2TxHash]; require(amount > 0, "y1"); - // Change the total deposited amount by the user - _verifyDepositLimit(_l1Token, _depositSender, amount, true); - delete depositAmount[_depositSender][_l1Token][_l2TxHash]; // Withdraw funds IERC20(_l1Token).safeTransfer(_depositSender, amount); @@ -300,7 +288,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof - ) external nonReentrant senderCanCallFunction(allowList) { + ) external nonReentrant { require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "pw"); L2Message memory l2ToL1Message = L2Message({ @@ -340,19 +328,6 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua (amount, offset) = UnsafeBytes.readUint256(_l2ToL1message, offset); } - /// @dev Verify the deposit limit is reached to its cap or not - function _verifyDepositLimit(address _l1Token, address _depositor, uint256 _amount, bool _claiming) internal { - IAllowList.Deposit memory limitData = IAllowList(allowList).getTokenDepositLimitData(_l1Token); - if (!limitData.depositLimitation) return; // no deposit limitation is placed for this token - - if (_claiming) { - totalDepositedAmountPerUser[_l1Token][_depositor] -= _amount; - } else { - require(totalDepositedAmountPerUser[_l1Token][_depositor] + _amount <= limitData.depositCap, "d1"); - totalDepositedAmountPerUser[_l1Token][_depositor] += _amount; - } - } - /// @return The L2 token address that would be minted for deposit of the given L1 token function l2TokenAddress(address _l1Token) public view returns (address) { bytes32 constructorInputHash = keccak256(abi.encode(address(l2TokenBeacon), "")); diff --git a/ethereum/contracts/bridge/L1WethBridge.sol b/l1-contracts/contracts/bridge/L1WethBridge.sol similarity index 96% rename from ethereum/contracts/bridge/L1WethBridge.sol rename to l1-contracts/contracts/bridge/L1WethBridge.sol index c58968a25..70b1d1a55 100644 --- a/ethereum/contracts/bridge/L1WethBridge.sol +++ b/l1-contracts/contracts/bridge/L1WethBridge.sol @@ -9,11 +9,9 @@ import "./interfaces/IL2WethBridge.sol"; import "./interfaces/IL2Bridge.sol"; import "./interfaces/IWETH9.sol"; import "../zksync/interfaces/IZkSync.sol"; -import "../common/interfaces/IAllowList.sol"; import "./libraries/BridgeInitializationHelper.sol"; -import "../common/AllowListed.sol"; import "../common/libraries/UnsafeBytes.sol"; import "../common/ReentrancyGuard.sol"; import "../common/libraries/L2ContractHelper.sol"; @@ -34,7 +32,7 @@ import "../vendor/AddressAliasHelper.sol"; /// @dev For withdrawals, the contract receives ETH from the L2 WETH bridge contract, wraps it into /// WETH, and sends the WETH to the L1 recipient. /// @dev The `L1WethBridge` contract works in conjunction with its L2 counterpart, `L2WethBridge`. -contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard { +contract L1WethBridge is IL1Bridge, ReentrancyGuard { using SafeERC20 for IERC20; /// @dev Event emitted when ETH is received by the contract. @@ -43,9 +41,6 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard { /// @dev The address of the WETH token on L1 address payable public immutable l1WethAddress; - /// @dev The smart contract that manages the list with permission to call contract functions - IAllowList public immutable allowList; - /// @dev zkSync smart contract that is used to operate with L2 via asynchronous L2 <-> L1 communication IZkSync public immutable zkSync; @@ -61,10 +56,9 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard { /// @dev Contract is expected to be used as proxy implementation. /// @dev Initialize the implementation to prevent Parity hack. - constructor(address payable _l1WethAddress, IZkSync _zkSync, IAllowList _allowList) reentrancyGuardInitializer { + constructor(address payable _l1WethAddress, IZkSync _zkSync) reentrancyGuardInitializer { l1WethAddress = _l1WethAddress; zkSync = _zkSync; - allowList = _allowList; } /// @dev Initializes a contract bridge for later use. Expected to be used in the proxy @@ -166,7 +160,7 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard { uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte, address _refundRecipient - ) external payable nonReentrant senderCanCallFunction(allowList) returns (bytes32 txHash) { + ) external payable nonReentrant returns (bytes32 txHash) { require(_l1Token == l1WethAddress, "Invalid L1 token address"); require(_amount != 0, "Amount cannot be zero"); @@ -240,7 +234,7 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard { uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof - ) external nonReentrant senderCanCallFunction(allowList) { + ) external nonReentrant { require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "Withdrawal is already finalized"); (address l1WethWithdrawReceiver, uint256 amount) = _parseL2EthWithdrawalMessage(_message); diff --git a/ethereum/contracts/bridge/interfaces/IL1Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1Bridge.sol similarity index 100% rename from ethereum/contracts/bridge/interfaces/IL1Bridge.sol rename to l1-contracts/contracts/bridge/interfaces/IL1Bridge.sol diff --git a/ethereum/contracts/bridge/interfaces/IL1BridgeLegacy.sol b/l1-contracts/contracts/bridge/interfaces/IL1BridgeLegacy.sol similarity index 100% rename from ethereum/contracts/bridge/interfaces/IL1BridgeLegacy.sol rename to l1-contracts/contracts/bridge/interfaces/IL1BridgeLegacy.sol diff --git a/ethereum/contracts/bridge/interfaces/IL2Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol similarity index 100% rename from ethereum/contracts/bridge/interfaces/IL2Bridge.sol rename to l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol diff --git a/ethereum/contracts/bridge/interfaces/IL2ERC20Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL2ERC20Bridge.sol similarity index 100% rename from ethereum/contracts/bridge/interfaces/IL2ERC20Bridge.sol rename to l1-contracts/contracts/bridge/interfaces/IL2ERC20Bridge.sol diff --git a/ethereum/contracts/bridge/interfaces/IL2WethBridge.sol b/l1-contracts/contracts/bridge/interfaces/IL2WethBridge.sol similarity index 100% rename from ethereum/contracts/bridge/interfaces/IL2WethBridge.sol rename to l1-contracts/contracts/bridge/interfaces/IL2WethBridge.sol diff --git a/ethereum/contracts/bridge/interfaces/IWETH9.sol b/l1-contracts/contracts/bridge/interfaces/IWETH9.sol similarity index 100% rename from ethereum/contracts/bridge/interfaces/IWETH9.sol rename to l1-contracts/contracts/bridge/interfaces/IWETH9.sol diff --git a/ethereum/contracts/bridge/libraries/BridgeInitializationHelper.sol b/l1-contracts/contracts/bridge/libraries/BridgeInitializationHelper.sol similarity index 100% rename from ethereum/contracts/bridge/libraries/BridgeInitializationHelper.sol rename to l1-contracts/contracts/bridge/libraries/BridgeInitializationHelper.sol diff --git a/ethereum/contracts/common/Dependencies.sol b/l1-contracts/contracts/common/Dependencies.sol similarity index 100% rename from ethereum/contracts/common/Dependencies.sol rename to l1-contracts/contracts/common/Dependencies.sol diff --git a/ethereum/contracts/common/L2ContractAddresses.sol b/l1-contracts/contracts/common/L2ContractAddresses.sol similarity index 100% rename from ethereum/contracts/common/L2ContractAddresses.sol rename to l1-contracts/contracts/common/L2ContractAddresses.sol diff --git a/ethereum/contracts/common/ReentrancyGuard.sol b/l1-contracts/contracts/common/ReentrancyGuard.sol similarity index 100% rename from ethereum/contracts/common/ReentrancyGuard.sol rename to l1-contracts/contracts/common/ReentrancyGuard.sol diff --git a/ethereum/contracts/common/interfaces/IL2ContractDeployer.sol b/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol similarity index 100% rename from ethereum/contracts/common/interfaces/IL2ContractDeployer.sol rename to l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol diff --git a/ethereum/contracts/common/libraries/L2ContractHelper.sol b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol similarity index 100% rename from ethereum/contracts/common/libraries/L2ContractHelper.sol rename to l1-contracts/contracts/common/libraries/L2ContractHelper.sol diff --git a/ethereum/contracts/common/libraries/UncheckedMath.sol b/l1-contracts/contracts/common/libraries/UncheckedMath.sol similarity index 100% rename from ethereum/contracts/common/libraries/UncheckedMath.sol rename to l1-contracts/contracts/common/libraries/UncheckedMath.sol diff --git a/ethereum/contracts/common/libraries/UnsafeBytes.sol b/l1-contracts/contracts/common/libraries/UnsafeBytes.sol similarity index 100% rename from ethereum/contracts/common/libraries/UnsafeBytes.sol rename to l1-contracts/contracts/common/libraries/UnsafeBytes.sol diff --git a/ethereum/contracts/dev-contracts/ConstructorForwarder.sol b/l1-contracts/contracts/dev-contracts/ConstructorForwarder.sol similarity index 100% rename from ethereum/contracts/dev-contracts/ConstructorForwarder.sol rename to l1-contracts/contracts/dev-contracts/ConstructorForwarder.sol diff --git a/ethereum/contracts/dev-contracts/EventOnFallback.sol b/l1-contracts/contracts/dev-contracts/EventOnFallback.sol similarity index 100% rename from ethereum/contracts/dev-contracts/EventOnFallback.sol rename to l1-contracts/contracts/dev-contracts/EventOnFallback.sol diff --git a/ethereum/contracts/dev-contracts/Forwarder.sol b/l1-contracts/contracts/dev-contracts/Forwarder.sol similarity index 100% rename from ethereum/contracts/dev-contracts/Forwarder.sol rename to l1-contracts/contracts/dev-contracts/Forwarder.sol diff --git a/ethereum/contracts/dev-contracts/Multicall.sol b/l1-contracts/contracts/dev-contracts/Multicall.sol similarity index 100% rename from ethereum/contracts/dev-contracts/Multicall.sol rename to l1-contracts/contracts/dev-contracts/Multicall.sol diff --git a/ethereum/contracts/dev-contracts/Multicall3.sol b/l1-contracts/contracts/dev-contracts/Multicall3.sol similarity index 100% rename from ethereum/contracts/dev-contracts/Multicall3.sol rename to l1-contracts/contracts/dev-contracts/Multicall3.sol diff --git a/ethereum/contracts/dev-contracts/ReturnSomething.sol b/l1-contracts/contracts/dev-contracts/ReturnSomething.sol similarity index 100% rename from ethereum/contracts/dev-contracts/ReturnSomething.sol rename to l1-contracts/contracts/dev-contracts/ReturnSomething.sol diff --git a/ethereum/contracts/dev-contracts/RevertFallback.sol b/l1-contracts/contracts/dev-contracts/RevertFallback.sol similarity index 100% rename from ethereum/contracts/dev-contracts/RevertFallback.sol rename to l1-contracts/contracts/dev-contracts/RevertFallback.sol diff --git a/ethereum/contracts/dev-contracts/RevertReceiveAccount.sol b/l1-contracts/contracts/dev-contracts/RevertReceiveAccount.sol similarity index 100% rename from ethereum/contracts/dev-contracts/RevertReceiveAccount.sol rename to l1-contracts/contracts/dev-contracts/RevertReceiveAccount.sol diff --git a/ethereum/contracts/dev-contracts/RevertTransferERC20.sol b/l1-contracts/contracts/dev-contracts/RevertTransferERC20.sol similarity index 100% rename from ethereum/contracts/dev-contracts/RevertTransferERC20.sol rename to l1-contracts/contracts/dev-contracts/RevertTransferERC20.sol diff --git a/ethereum/contracts/dev-contracts/SingletonFactory.sol b/l1-contracts/contracts/dev-contracts/SingletonFactory.sol similarity index 100% rename from ethereum/contracts/dev-contracts/SingletonFactory.sol rename to l1-contracts/contracts/dev-contracts/SingletonFactory.sol diff --git a/ethereum/contracts/dev-contracts/TestnetERC20Token.sol b/l1-contracts/contracts/dev-contracts/TestnetERC20Token.sol similarity index 100% rename from ethereum/contracts/dev-contracts/TestnetERC20Token.sol rename to l1-contracts/contracts/dev-contracts/TestnetERC20Token.sol diff --git a/ethereum/contracts/dev-contracts/WETH9.sol b/l1-contracts/contracts/dev-contracts/WETH9.sol similarity index 100% rename from ethereum/contracts/dev-contracts/WETH9.sol rename to l1-contracts/contracts/dev-contracts/WETH9.sol diff --git a/ethereum/contracts/dev-contracts/test/AdminFacetTest.sol b/l1-contracts/contracts/dev-contracts/test/AdminFacetTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/AdminFacetTest.sol rename to l1-contracts/contracts/dev-contracts/test/AdminFacetTest.sol diff --git a/ethereum/contracts/dev-contracts/test/CustomUpgradeTest.sol b/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol similarity index 96% rename from ethereum/contracts/dev-contracts/test/CustomUpgradeTest.sol rename to l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol index 25df17ad8..fcd3f5c7f 100644 --- a/ethereum/contracts/dev-contracts/test/CustomUpgradeTest.sol +++ b/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol @@ -38,7 +38,6 @@ contract CustomUpgradeTest is BaseZkSyncUpgrade { _proposedUpgrade.newProtocolVersion ); - _setAllowList(IAllowList(_proposedUpgrade.newAllowList)); _postUpgrade(_proposedUpgrade.postUpgradeCalldata); emit UpgradeComplete(_proposedUpgrade.newProtocolVersion, txHash, _proposedUpgrade); diff --git a/ethereum/contracts/dev-contracts/test/DiamondCutTestContract.sol b/l1-contracts/contracts/dev-contracts/test/DiamondCutTestContract.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/DiamondCutTestContract.sol rename to l1-contracts/contracts/dev-contracts/test/DiamondCutTestContract.sol diff --git a/ethereum/contracts/dev-contracts/test/DiamondProxyTest.sol b/l1-contracts/contracts/dev-contracts/test/DiamondProxyTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/DiamondProxyTest.sol rename to l1-contracts/contracts/dev-contracts/test/DiamondProxyTest.sol diff --git a/ethereum/contracts/dev-contracts/test/DummyERC20BytesTransferReturnValue.sol b/l1-contracts/contracts/dev-contracts/test/DummyERC20BytesTransferReturnValue.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/DummyERC20BytesTransferReturnValue.sol rename to l1-contracts/contracts/dev-contracts/test/DummyERC20BytesTransferReturnValue.sol diff --git a/ethereum/contracts/dev-contracts/test/DummyERC20NoTransferReturnValue.sol b/l1-contracts/contracts/dev-contracts/test/DummyERC20NoTransferReturnValue.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/DummyERC20NoTransferReturnValue.sol rename to l1-contracts/contracts/dev-contracts/test/DummyERC20NoTransferReturnValue.sol diff --git a/ethereum/contracts/dev-contracts/test/DummyExecutor.sol b/l1-contracts/contracts/dev-contracts/test/DummyExecutor.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/DummyExecutor.sol rename to l1-contracts/contracts/dev-contracts/test/DummyExecutor.sol diff --git a/ethereum/contracts/dev-contracts/test/ExecutorProvingTest.sol b/l1-contracts/contracts/dev-contracts/test/ExecutorProvingTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/ExecutorProvingTest.sol rename to l1-contracts/contracts/dev-contracts/test/ExecutorProvingTest.sol diff --git a/ethereum/contracts/dev-contracts/test/L1ERC20BridgeTest.sol b/l1-contracts/contracts/dev-contracts/test/L1ERC20BridgeTest.sol similarity index 58% rename from ethereum/contracts/dev-contracts/test/L1ERC20BridgeTest.sol rename to l1-contracts/contracts/dev-contracts/test/L1ERC20BridgeTest.sol index 04f2aac73..dea0275d3 100644 --- a/ethereum/contracts/dev-contracts/test/L1ERC20BridgeTest.sol +++ b/l1-contracts/contracts/dev-contracts/test/L1ERC20BridgeTest.sol @@ -6,11 +6,7 @@ import "../../bridge/L1ERC20Bridge.sol"; /// @author Matter Labs contract L1ERC20BridgeTest is L1ERC20Bridge { - constructor(IZkSync _zkSync, IAllowList _allowList) L1ERC20Bridge(_zkSync, _allowList) {} - - function getAllowList() public view returns (IAllowList) { - return allowList; - } + constructor(IZkSync _zkSync) L1ERC20Bridge(_zkSync) {} function getZkSyncMailbox() public view returns (IMailbox) { return zkSync; diff --git a/ethereum/contracts/dev-contracts/test/MerkleTest.sol b/l1-contracts/contracts/dev-contracts/test/MerkleTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/MerkleTest.sol rename to l1-contracts/contracts/dev-contracts/test/MerkleTest.sol diff --git a/ethereum/contracts/dev-contracts/test/MockExecutor.sol b/l1-contracts/contracts/dev-contracts/test/MockExecutor.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/MockExecutor.sol rename to l1-contracts/contracts/dev-contracts/test/MockExecutor.sol diff --git a/ethereum/contracts/dev-contracts/test/PriorityQueueTest.sol b/l1-contracts/contracts/dev-contracts/test/PriorityQueueTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/PriorityQueueTest.sol rename to l1-contracts/contracts/dev-contracts/test/PriorityQueueTest.sol diff --git a/ethereum/contracts/dev-contracts/test/ReenterGovernance.sol b/l1-contracts/contracts/dev-contracts/test/ReenterGovernance.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/ReenterGovernance.sol rename to l1-contracts/contracts/dev-contracts/test/ReenterGovernance.sol diff --git a/ethereum/contracts/dev-contracts/test/UnsafeBytesTest.sol b/l1-contracts/contracts/dev-contracts/test/UnsafeBytesTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/UnsafeBytesTest.sol rename to l1-contracts/contracts/dev-contracts/test/UnsafeBytesTest.sol diff --git a/ethereum/contracts/dev-contracts/test/VerifierRecursiveTest.sol b/l1-contracts/contracts/dev-contracts/test/VerifierRecursiveTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/VerifierRecursiveTest.sol rename to l1-contracts/contracts/dev-contracts/test/VerifierRecursiveTest.sol diff --git a/ethereum/contracts/dev-contracts/test/VerifierTest.sol b/l1-contracts/contracts/dev-contracts/test/VerifierTest.sol similarity index 100% rename from ethereum/contracts/dev-contracts/test/VerifierTest.sol rename to l1-contracts/contracts/dev-contracts/test/VerifierTest.sol diff --git a/ethereum/contracts/governance/Governance.sol b/l1-contracts/contracts/governance/Governance.sol similarity index 100% rename from ethereum/contracts/governance/Governance.sol rename to l1-contracts/contracts/governance/Governance.sol diff --git a/ethereum/contracts/governance/IGovernance.sol b/l1-contracts/contracts/governance/IGovernance.sol similarity index 100% rename from ethereum/contracts/governance/IGovernance.sol rename to l1-contracts/contracts/governance/IGovernance.sol diff --git a/ethereum/contracts/upgrades/BaseZkSyncUpgrade.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol similarity index 95% rename from ethereum/contracts/upgrades/BaseZkSyncUpgrade.sol rename to l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol index c6f930d5c..b72f36563 100644 --- a/ethereum/contracts/upgrades/BaseZkSyncUpgrade.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol @@ -60,9 +60,6 @@ abstract contract BaseZkSyncUpgrade is Base { /// @notice Notifies about complete upgrade event UpgradeComplete(uint256 indexed newProtocolVersion, bytes32 indexed l2UpgradeTxHash, ProposedUpgrade upgrade); - /// @notice Allow list address changed - event NewAllowList(address indexed oldAllowList, address indexed newAllowList); - /// @notice The main function that will be provided by the upgrade proxy function upgrade(ProposedUpgrade calldata _proposedUpgrade) public virtual returns (bytes32) { // Note that due to commitment delay, the timestamp of the L2 upgrade batch may be earlier than the timestamp @@ -232,16 +229,4 @@ abstract contract BaseZkSyncUpgrade is Base { s.protocolVersion = _newProtocolVersion; emit NewProtocolVersion(previousProtocolVersion, _newProtocolVersion); } - - /// @notice Change the address of the allow list smart contract - /// @param _newAllowList Allow list smart contract address - function _setAllowList(IAllowList _newAllowList) internal { - if (_newAllowList == IAllowList(address(0))) { - return; - } - - IAllowList oldAllowList = s.allowList; - s.allowList = _newAllowList; - emit NewAllowList(address(oldAllowList), address(_newAllowList)); - } } diff --git a/ethereum/contracts/upgrades/DefaultUpgrade.sol b/l1-contracts/contracts/upgrades/DefaultUpgrade.sol similarity index 96% rename from ethereum/contracts/upgrades/DefaultUpgrade.sol rename to l1-contracts/contracts/upgrades/DefaultUpgrade.sol index 23319b6b2..cd2bdd29f 100644 --- a/ethereum/contracts/upgrades/DefaultUpgrade.sol +++ b/l1-contracts/contracts/upgrades/DefaultUpgrade.sol @@ -37,7 +37,6 @@ contract DefaultUpgrade is BaseZkSyncUpgrade { _proposedUpgrade.newProtocolVersion ); - _setAllowList(IAllowList(_proposedUpgrade.newAllowList)); _postUpgrade(_proposedUpgrade.postUpgradeCalldata); emit UpgradeComplete(_proposedUpgrade.newProtocolVersion, txHash, _proposedUpgrade); diff --git a/ethereum/contracts/vendor/AddressAliasHelper.sol b/l1-contracts/contracts/vendor/AddressAliasHelper.sol similarity index 100% rename from ethereum/contracts/vendor/AddressAliasHelper.sol rename to l1-contracts/contracts/vendor/AddressAliasHelper.sol diff --git a/ethereum/contracts/zksync/Config.sol b/l1-contracts/contracts/zksync/Config.sol similarity index 100% rename from ethereum/contracts/zksync/Config.sol rename to l1-contracts/contracts/zksync/Config.sol diff --git a/ethereum/contracts/zksync/DiamondInit.sol b/l1-contracts/contracts/zksync/DiamondInit.sol similarity index 95% rename from ethereum/contracts/zksync/DiamondInit.sol rename to l1-contracts/contracts/zksync/DiamondInit.sol index 8a46dbd10..8622c31e8 100644 --- a/ethereum/contracts/zksync/DiamondInit.sol +++ b/l1-contracts/contracts/zksync/DiamondInit.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.20; -import {IAllowList} from "../common/interfaces/IAllowList.sol"; import {IVerifier} from "./interfaces/IVerifier.sol"; import {IExecutor} from "./interfaces/IExecutor.sol"; import {Diamond} from "./libraries/Diamond.sol"; @@ -25,7 +24,6 @@ contract DiamondInit is Base { /// @param _genesisBatchHash Batch hash of the genesis (initial) batch /// @param _genesisIndexRepeatedStorageChanges The serial number of the shortcut storage key for genesis batch /// @param _genesisBatchCommitment The zk-proof commitment for the genesis batch - /// @param _allowList The address of the allow list smart contract /// @param _verifierParams Verifier config parameters that describes the circuit to be verified /// @param _zkPorterIsAvailable The availability of zk porter shard /// @param _l2BootloaderBytecodeHash The hash of bootloader L2 bytecode @@ -38,7 +36,6 @@ contract DiamondInit is Base { bytes32 genesisBatchHash; uint64 genesisIndexRepeatedStorageChanges; bytes32 genesisBatchCommitment; - IAllowList allowList; VerifierParams verifierParams; bool zkPorterIsAvailable; bytes32 l2BootloaderBytecodeHash; @@ -76,7 +73,6 @@ contract DiamondInit is Base { ); s.storedBatchHashes[0] = keccak256(abi.encode(storedBatchZero)); - s.allowList = _initalizeData.allowList; s.verifierParams = _initalizeData.verifierParams; s.zkPorterIsAvailable = _initalizeData.zkPorterIsAvailable; s.l2BootloaderBytecodeHash = _initalizeData.l2BootloaderBytecodeHash; diff --git a/ethereum/contracts/zksync/DiamondProxy.sol b/l1-contracts/contracts/zksync/DiamondProxy.sol similarity index 100% rename from ethereum/contracts/zksync/DiamondProxy.sol rename to l1-contracts/contracts/zksync/DiamondProxy.sol diff --git a/ethereum/contracts/zksync/Storage.sol b/l1-contracts/contracts/zksync/Storage.sol similarity index 99% rename from ethereum/contracts/zksync/Storage.sol rename to l1-contracts/contracts/zksync/Storage.sol index d68b9d76e..a8e4f2401 100644 --- a/ethereum/contracts/zksync/Storage.sol +++ b/l1-contracts/contracts/zksync/Storage.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.20; import "./../zksync/interfaces/IVerifier.sol"; -import "../common/interfaces/IAllowList.sol"; import "./libraries/PriorityQueue.sol"; /// @notice Indicates whether an upgrade is initiated and if yes what type @@ -102,7 +101,7 @@ struct AppStorage { /// @dev Container that stores transactions requested from L1 PriorityQueue.Queue priorityQueue; /// @dev The smart contract that manages the list with permission to call contract functions - IAllowList allowList; + address __DEPRECATED_allowList; /// @notice Part of the configuration parameters of ZKP circuits. Used as an input for the verifier smart contract VerifierParams verifierParams; /// @notice Bytecode hash of bootloader program. diff --git a/ethereum/contracts/zksync/ValidatorTimelock.sol b/l1-contracts/contracts/zksync/ValidatorTimelock.sol similarity index 100% rename from ethereum/contracts/zksync/ValidatorTimelock.sol rename to l1-contracts/contracts/zksync/ValidatorTimelock.sol diff --git a/ethereum/contracts/zksync/Verifier.sol b/l1-contracts/contracts/zksync/Verifier.sol similarity index 100% rename from ethereum/contracts/zksync/Verifier.sol rename to l1-contracts/contracts/zksync/Verifier.sol diff --git a/ethereum/contracts/zksync/facets/Admin.sol b/l1-contracts/contracts/zksync/facets/Admin.sol similarity index 99% rename from ethereum/contracts/zksync/facets/Admin.sol rename to l1-contracts/contracts/zksync/facets/Admin.sol index 9177afb71..0990a13cf 100644 --- a/ethereum/contracts/zksync/facets/Admin.sol +++ b/l1-contracts/contracts/zksync/facets/Admin.sol @@ -40,7 +40,7 @@ contract AdminFacet is Base, IAdmin { /// @notice Starts the transfer of admin rights. Only the current governor or admin can propose a new pending one. /// @notice New admin can accept admin rights by calling `acceptAdmin` function. /// @param _newPendingAdmin Address of the new admin - function setPendingAdmin(address _newPendingAdmin) external onlyGovernorOrAdmin { + function setPendingAdmin(address _newPendingAdmin) external onlyGovernor { // Save previous value into the stack to put it into the event later address oldPendingAdmin = s.pendingAdmin; // Change pending admin diff --git a/ethereum/contracts/zksync/facets/Base.sol b/l1-contracts/contracts/zksync/facets/Base.sol similarity index 91% rename from ethereum/contracts/zksync/facets/Base.sol rename to l1-contracts/contracts/zksync/facets/Base.sol index 8d158ae22..af3cf72c9 100644 --- a/ethereum/contracts/zksync/facets/Base.sol +++ b/l1-contracts/contracts/zksync/facets/Base.sol @@ -4,12 +4,11 @@ pragma solidity 0.8.20; import "../Storage.sol"; import "../../common/ReentrancyGuard.sol"; -import "../../common/AllowListed.sol"; /// @title Base contract containing functions accessible to the other facets. /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev -contract Base is ReentrancyGuard, AllowListed { +contract Base is ReentrancyGuard { AppStorage internal s; /// @notice Checks that the message sender is an active governor diff --git a/ethereum/contracts/zksync/facets/Executor.sol b/l1-contracts/contracts/zksync/facets/Executor.sol similarity index 100% rename from ethereum/contracts/zksync/facets/Executor.sol rename to l1-contracts/contracts/zksync/facets/Executor.sol diff --git a/ethereum/contracts/zksync/facets/Getters.sol b/l1-contracts/contracts/zksync/facets/Getters.sol similarity index 98% rename from ethereum/contracts/zksync/facets/Getters.sol rename to l1-contracts/contracts/zksync/facets/Getters.sol index a5945c34c..2a181b138 100644 --- a/ethereum/contracts/zksync/facets/Getters.sol +++ b/l1-contracts/contracts/zksync/facets/Getters.sol @@ -149,11 +149,6 @@ contract GettersFacet is Base, IGetters, ILegacyGetters { return s.priorityTxMaxGasLimit; } - /// @return The allow list smart contract - function getAllowList() external view returns (address) { - return address(s.allowList); - } - /// @return Whether the selector can be frozen by the governor or always accessible function isFunctionFreezable(bytes4 _selector) external view returns (bool) { Diamond.DiamondStorage storage ds = Diamond.getDiamondStorage(); diff --git a/ethereum/contracts/zksync/facets/Mailbox.sol b/l1-contracts/contracts/zksync/facets/Mailbox.sol similarity index 99% rename from ethereum/contracts/zksync/facets/Mailbox.sol rename to l1-contracts/contracts/zksync/facets/Mailbox.sol index a9c110b4e..324a4d5d5 100644 --- a/ethereum/contracts/zksync/facets/Mailbox.sol +++ b/l1-contracts/contracts/zksync/facets/Mailbox.sol @@ -13,7 +13,6 @@ import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; import {UnsafeBytes} from "../../common/libraries/UnsafeBytes.sol"; import {L2ContractHelper} from "../../common/libraries/L2ContractHelper.sol"; import {AddressAliasHelper} from "../../vendor/AddressAliasHelper.sol"; -import {IAllowList} from "../../common/interfaces/IAllowList.sol"; import {Base} from "./Base.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, FAIR_L2_GAS_PRICE, L1_GAS_PER_PUBDATA_BYTE, L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, PRIORITY_OPERATION_L2_TX_TYPE, PRIORITY_EXPIRATION, MAX_NEW_FACTORY_DEPS} from "../Config.sol"; import {L2_BOOTLOADER_ADDRESS, L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_ETH_TOKEN_SYSTEM_CONTRACT_ADDR} from "../../common/L2ContractAddresses.sol"; diff --git a/ethereum/contracts/zksync/interfaces/IAdmin.sol b/l1-contracts/contracts/zksync/interfaces/IAdmin.sol similarity index 100% rename from ethereum/contracts/zksync/interfaces/IAdmin.sol rename to l1-contracts/contracts/zksync/interfaces/IAdmin.sol diff --git a/ethereum/contracts/zksync/interfaces/IBase.sol b/l1-contracts/contracts/zksync/interfaces/IBase.sol similarity index 100% rename from ethereum/contracts/zksync/interfaces/IBase.sol rename to l1-contracts/contracts/zksync/interfaces/IBase.sol diff --git a/ethereum/contracts/zksync/interfaces/IExecutor.sol b/l1-contracts/contracts/zksync/interfaces/IExecutor.sol similarity index 100% rename from ethereum/contracts/zksync/interfaces/IExecutor.sol rename to l1-contracts/contracts/zksync/interfaces/IExecutor.sol diff --git a/ethereum/contracts/zksync/interfaces/IGetters.sol b/l1-contracts/contracts/zksync/interfaces/IGetters.sol similarity index 98% rename from ethereum/contracts/zksync/interfaces/IGetters.sol rename to l1-contracts/contracts/zksync/interfaces/IGetters.sol index 63b745cb8..46310b556 100644 --- a/ethereum/contracts/zksync/interfaces/IGetters.sol +++ b/l1-contracts/contracts/zksync/interfaces/IGetters.sol @@ -53,8 +53,6 @@ interface IGetters is IBase { function getPriorityTxMaxGasLimit() external view returns (uint256); - function getAllowList() external view returns (address); - function isEthWithdrawalFinalized(uint256 _l2BatchNumber, uint256 _l2MessageIndex) external view returns (bool); /*////////////////////////////////////////////////////////////// diff --git a/ethereum/contracts/zksync/interfaces/ILegacyGetters.sol b/l1-contracts/contracts/zksync/interfaces/ILegacyGetters.sol similarity index 100% rename from ethereum/contracts/zksync/interfaces/ILegacyGetters.sol rename to l1-contracts/contracts/zksync/interfaces/ILegacyGetters.sol diff --git a/ethereum/contracts/zksync/interfaces/IMailbox.sol b/l1-contracts/contracts/zksync/interfaces/IMailbox.sol similarity index 100% rename from ethereum/contracts/zksync/interfaces/IMailbox.sol rename to l1-contracts/contracts/zksync/interfaces/IMailbox.sol diff --git a/ethereum/contracts/zksync/interfaces/IVerifier.sol b/l1-contracts/contracts/zksync/interfaces/IVerifier.sol similarity index 100% rename from ethereum/contracts/zksync/interfaces/IVerifier.sol rename to l1-contracts/contracts/zksync/interfaces/IVerifier.sol diff --git a/ethereum/contracts/zksync/interfaces/IZkSync.sol b/l1-contracts/contracts/zksync/interfaces/IZkSync.sol similarity index 100% rename from ethereum/contracts/zksync/interfaces/IZkSync.sol rename to l1-contracts/contracts/zksync/interfaces/IZkSync.sol diff --git a/ethereum/contracts/zksync/libraries/Diamond.sol b/l1-contracts/contracts/zksync/libraries/Diamond.sol similarity index 100% rename from ethereum/contracts/zksync/libraries/Diamond.sol rename to l1-contracts/contracts/zksync/libraries/Diamond.sol diff --git a/ethereum/contracts/zksync/libraries/LibMap.sol b/l1-contracts/contracts/zksync/libraries/LibMap.sol similarity index 100% rename from ethereum/contracts/zksync/libraries/LibMap.sol rename to l1-contracts/contracts/zksync/libraries/LibMap.sol diff --git a/ethereum/contracts/zksync/libraries/Merkle.sol b/l1-contracts/contracts/zksync/libraries/Merkle.sol similarity index 100% rename from ethereum/contracts/zksync/libraries/Merkle.sol rename to l1-contracts/contracts/zksync/libraries/Merkle.sol diff --git a/ethereum/contracts/zksync/libraries/PriorityQueue.sol b/l1-contracts/contracts/zksync/libraries/PriorityQueue.sol similarity index 100% rename from ethereum/contracts/zksync/libraries/PriorityQueue.sol rename to l1-contracts/contracts/zksync/libraries/PriorityQueue.sol diff --git a/ethereum/contracts/zksync/libraries/TransactionValidator.sol b/l1-contracts/contracts/zksync/libraries/TransactionValidator.sol similarity index 100% rename from ethereum/contracts/zksync/libraries/TransactionValidator.sol rename to l1-contracts/contracts/zksync/libraries/TransactionValidator.sol diff --git a/ethereum/contracts/zksync/upgrade-initializers/DIamondUpgradeInit2.sol b/l1-contracts/contracts/zksync/upgrade-initializers/DIamondUpgradeInit2.sol similarity index 100% rename from ethereum/contracts/zksync/upgrade-initializers/DIamondUpgradeInit2.sol rename to l1-contracts/contracts/zksync/upgrade-initializers/DIamondUpgradeInit2.sol diff --git a/ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit1.sol b/l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit1.sol similarity index 100% rename from ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit1.sol rename to l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit1.sol diff --git a/ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit3.sol b/l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit3.sol similarity index 95% rename from ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit3.sol rename to l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit3.sol index 488da94c7..5aa4b3b3f 100644 --- a/ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit3.sol +++ b/l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit3.sol @@ -43,14 +43,14 @@ interface IOldDiamondCut { contract DiamondUpgradeInit3 is Base { function upgrade( uint256 _priorityTxMaxGasLimit, - IAllowList _allowList, + address _allowList, IVerifier _verifier ) external payable returns (bytes32) { // Zero out the deprecated storage slots delete s.__DEPRECATED_diamondCutStorage; s.priorityTxMaxGasLimit = _priorityTxMaxGasLimit; - s.allowList = _allowList; + s.__DEPRECATED_allowList = _allowList; s.verifier = _verifier; return Diamond.DIAMOND_INIT_SUCCESS_RETURN_VALUE; diff --git a/ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit4.sol b/l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit4.sol similarity index 100% rename from ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit4.sol rename to l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit4.sol diff --git a/ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit5.sol b/l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit5.sol similarity index 100% rename from ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit5.sol rename to l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit5.sol diff --git a/ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit6.sol b/l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit6.sol similarity index 100% rename from ethereum/contracts/zksync/upgrade-initializers/DiamondUpgradeInit6.sol rename to l1-contracts/contracts/zksync/upgrade-initializers/DiamondUpgradeInit6.sol diff --git a/ethereum/foundry.toml b/l1-contracts/foundry.toml similarity index 100% rename from ethereum/foundry.toml rename to l1-contracts/foundry.toml diff --git a/ethereum/hardhat.config.ts b/l1-contracts/hardhat.config.ts similarity index 100% rename from ethereum/hardhat.config.ts rename to l1-contracts/hardhat.config.ts diff --git a/ethereum/lib/forge-std b/l1-contracts/lib/forge-std similarity index 100% rename from ethereum/lib/forge-std rename to l1-contracts/lib/forge-std diff --git a/l1-contracts/lib/murky b/l1-contracts/lib/murky new file mode 160000 index 000000000..40de6e801 --- /dev/null +++ b/l1-contracts/lib/murky @@ -0,0 +1 @@ +Subproject commit 40de6e80117f39cda69d71b07b7c824adac91b29 diff --git a/ethereum/package.json b/l1-contracts/package.json similarity index 73% rename from ethereum/package.json rename to l1-contracts/package.json index 8228716da..cad2ba81d 100644 --- a/ethereum/package.json +++ b/l1-contracts/package.json @@ -1,10 +1,8 @@ { - "name": "l1-zksync-contracts", + "name": "l1-contracts", "version": "0.1.0", "license": "MIT", "devDependencies": { - "@matterlabs/eslint-config-typescript": "^1.1.2", - "@matterlabs/prettier-config": "^1.0.3", "@nomiclabs/hardhat-ethers": "^2.0.0", "@nomiclabs/hardhat-etherscan": "^3.1.0", "@nomiclabs/hardhat-solpp": "^2.0.0", @@ -16,8 +14,6 @@ "@types/chai": "^4.2.21", "@types/chai-as-promised": "^7.1.4", "@types/mocha": "^8.2.3", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "@typescript-eslint/parser": "^6.7.4", "argparse": "^1.0.10", "axios": "^0.21.1", "chai": "^4.3.4", @@ -25,10 +21,6 @@ "chalk": "^4.1.0", "collections": "^5.1.12", "commander": "^8.3.0", - "eslint": "^8.51.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.0", - "eslint-plugin-prettier": "^5.0.1", "ethereum-waffle": "^3.0.0", "ethereumjs-abi": "^0.6.8", "ethers": "^5.7.0", @@ -40,15 +32,11 @@ "hardhat-gas-reporter": "^1.0.9", "hardhat-typechain": "^0.3.3", "jsonwebtoken": "^8.5.1", - "markdownlint-cli": "^0.33.0", "merkletreejs": "^0.2.32", "mocha": "^9.0.2", "path": "^0.12.7", - "prettier": "^3.0.3", - "prettier-plugin-solidity": "^1.1.3", "querystring": "^0.2.0", "solc": "0.8.17", - "solhint": "^3.6.2", "solidity-coverage": "^0.8.2", "ts-generator": "^0.1.1", "ts-node": "^10.1.0", @@ -62,18 +50,10 @@ "test:foundry": "hardhat solpp && forge test", "test:fork": "CONTRACT_TESTS=1 TEST_CONTRACTS_FORK=1 yarn run hardhat test test/unit_tests/*.fork.ts --network hardhat", "coverage:foundry": "hardhat solpp && forge coverage", - "lint:check": "yarn lint:md && yarn lint:sol && yarn lint:ts && yarn prettier:check", - "lint:fix": "yarn lint:md --fix && yarn lint:sol --fix && yarn lint:ts --fix && yarn prettier:fix", - "lint:md": "markdownlint \"**/*.md\"", - "lint:sol": "solhint \"**/*.sol\"", - "lint:ts": "eslint .", - "prettier:check": "prettier --check \"**/*.{js,json,md,sol,ts,yaml}\"", - "prettier:fix": "prettier --write \"**/*.{js,json,md,sol,ts,yaml}\"", "deploy-no-build": "ts-node scripts/deploy.ts", "deploy-weth-bridges": "ts-node scripts/deploy-weth-bridges.ts", "initialize-weth-bridges": "ts-node scripts/initialize-weth-bridges.ts", "initialize-l2-weth-token": "ts-node scripts/initialize-l2-weth-token.ts", - "allow-list-manager": "ts-node scripts/allow-list-manager.ts", "deploy-erc20": "ts-node scripts/deploy-erc20.ts", "token-info": "ts-node scripts/token-info.ts", "deploy-testkit": "ts-node scripts/deploy-testkit.ts", @@ -81,9 +61,10 @@ "deploy-testnet-erc20": "ts-node scripts/deploy-testnet-token.ts", "read-variable": "ts-node scripts/read-variable.ts", "initialize-bridges": "ts-node scripts/initialize-bridges.ts", - "initialize-allow-list": "ts-node scripts/initialize-l1-allow-list.ts", "initialize-validator": "ts-node scripts/initialize-validator.ts", "initialize-governance": "ts-node scripts/initialize-governance.ts", + "migrate-governance": "ts-node scripts/migrate-governance.ts", + "display-governance": "ts-node scripts/display-governance.ts", "upgrade-1": "ts-node scripts/upgrades/upgrade-1.ts", "upgrade-2": "ts-node scripts/upgrades/upgrade-2.ts", "upgrade-3": "ts-node scripts/upgrades/upgrade-3.ts", diff --git a/ethereum/remappings.txt b/l1-contracts/remappings.txt similarity index 78% rename from ethereum/remappings.txt rename to l1-contracts/remappings.txt index 5c40cafaf..d882fbd10 100644 --- a/ethereum/remappings.txt +++ b/l1-contracts/remappings.txt @@ -4,4 +4,5 @@ ds-test/=lib/forge-std/lib/ds-test/src/ eth-gas-reporter/=node_modules/eth-gas-reporter/ forge-std/=lib/forge-std/src/ hardhat/=node_modules/hardhat/ -solpp/=cache/solpp-generated-contracts/ \ No newline at end of file +solpp/=cache/solpp-generated-contracts/ +murky/=lib/murky/src/ diff --git a/ethereum/scripts/deploy-erc20.ts b/l1-contracts/scripts/deploy-erc20.ts similarity index 100% rename from ethereum/scripts/deploy-erc20.ts rename to l1-contracts/scripts/deploy-erc20.ts diff --git a/ethereum/scripts/deploy-testkit.ts b/l1-contracts/scripts/deploy-testkit.ts similarity index 100% rename from ethereum/scripts/deploy-testkit.ts rename to l1-contracts/scripts/deploy-testkit.ts diff --git a/ethereum/scripts/deploy-testnet-token.ts b/l1-contracts/scripts/deploy-testnet-token.ts similarity index 100% rename from ethereum/scripts/deploy-testnet-token.ts rename to l1-contracts/scripts/deploy-testnet-token.ts diff --git a/ethereum/scripts/deploy-weth-bridges.ts b/l1-contracts/scripts/deploy-weth-bridges.ts similarity index 100% rename from ethereum/scripts/deploy-weth-bridges.ts rename to l1-contracts/scripts/deploy-weth-bridges.ts diff --git a/ethereum/scripts/deploy-withdrawal-helpers.ts b/l1-contracts/scripts/deploy-withdrawal-helpers.ts similarity index 100% rename from ethereum/scripts/deploy-withdrawal-helpers.ts rename to l1-contracts/scripts/deploy-withdrawal-helpers.ts diff --git a/ethereum/scripts/deploy.ts b/l1-contracts/scripts/deploy.ts similarity index 97% rename from ethereum/scripts/deploy.ts rename to l1-contracts/scripts/deploy.ts index afd0335f2..d6af12d55 100644 --- a/ethereum/scripts/deploy.ts +++ b/l1-contracts/scripts/deploy.ts @@ -80,8 +80,7 @@ async function main() { nonce++; await deployer.deployGovernance(create2Salt, { gasPrice, nonce }); - await deployer.deployAllowList(create2Salt, { gasPrice, nonce: nonce + 1 }); - await deployer.deployZkSyncContract(create2Salt, gasPrice, nonce + 2); + await deployer.deployZkSyncContract(create2Salt, gasPrice, nonce + 1); await deployer.deployBridgeContracts(create2Salt, gasPrice); // Do not pass nonce, since it was increment after deploying zkSync contracts await deployer.deployWethBridgeContracts(create2Salt, gasPrice); await deployer.deployValidatorTimelock(create2Salt, { gasPrice }); diff --git a/l1-contracts/scripts/display-governance.ts b/l1-contracts/scripts/display-governance.ts new file mode 100644 index 000000000..6dba44077 --- /dev/null +++ b/l1-contracts/scripts/display-governance.ts @@ -0,0 +1,106 @@ +/// Temporary script that generated the needed calldata for the migration of the governance. + +import { Command } from "commander"; +import { ethers, Wallet } from "ethers"; +import { Deployer } from "../src.ts/deploy"; +import { applyL1ToL2Alias, getAddressFromEnv } from "./utils"; +import * as fs from "fs"; + +import { UpgradeableBeaconFactory } from "../../zksync/typechain/UpgradeableBeaconFactory"; +import { Provider } from "zksync-web3"; + +const L2ERC20BridgeABI = JSON.parse( + fs + .readFileSync( + "../zksync/artifacts-zk/cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol/L2ERC20Bridge.json" + ) + .toString() +).abi; + +async function getERC20BeaconAddress(l2Erc20BridgeAddress: string) { + const provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + const contract = new ethers.Contract(l2Erc20BridgeAddress, L2ERC20BridgeABI, provider); + return await contract.l2TokenBeacon(); +} + +async function proxyGov(addr: string, prov: ethers.providers.Provider) { + const adminSlot = "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"; + return `0x${(await prov.getStorageAt(addr, adminSlot)).substring(26)}`; +} + +async function main() { + const program = new Command(); + + program.version("0.1.0").name("migrate-governance"); + + program.action(async () => { + // This action is very dangerous, and so we double check that the governance in env is the same + // one as the user provided manually. + const governanceAddressFromEnv = getAddressFromEnv("CONTRACTS_GOVERNANCE_ADDR").toLowerCase(); + const aliasedNewGovernor = applyL1ToL2Alias(governanceAddressFromEnv); + + console.log(`Using governance address from env: ${governanceAddressFromEnv}`); + console.log(`Aliased governance address from env: ${aliasedNewGovernor}`); + + // We won't be making any transactions with this wallet, we just need + // it to initialize the Deployer object. + const deployWallet = Wallet.createRandom().connect( + new ethers.providers.JsonRpcProvider(process.env.ETH_CLIENT_WEB3_URL) + ); + const deployer = new Deployer({ + deployWallet, + verbose: true, + }); + + // Firstly, we deploy the info about the L1 contracts + + const zkSync = deployer.zkSyncContract(deployWallet); + + console.log("zkSync governor: ", await zkSync.getGovernor()); + console.log("zkSync pendingGovernor: ", await zkSync.getPendingGovernor()); + + const validatorTimelock = deployer.validatorTimelock(deployWallet); + console.log("validatorTimelock governor: ", await validatorTimelock.owner()); + console.log("validatorTimelock pendingGovernor: ", await validatorTimelock.pendingOwner()); + + const l1Erc20Bridge = deployer.transparentUpgradableProxyContract( + deployer.addresses.Bridges.ERC20BridgeProxy, + deployWallet + ); + + console.log("l1Erc20Bridge governor: ", await proxyGov(l1Erc20Bridge.address, deployWallet.provider)); + + // Now, starting to deploy the info about the L2 contracts + + const deployWallet2 = Wallet.createRandom().connect( + new ethers.providers.JsonRpcProvider(process.env.API_WEB3_JSON_RPC_HTTP_URL) + ); + + const l2ERC20Bridge = deployer.transparentUpgradableProxyContract( + process.env.CONTRACTS_L2_ERC20_BRIDGE_ADDR!, + deployWallet2 + ); + console.log("l2ERC20Bridge governor: ", await proxyGov(l2ERC20Bridge.address, deployWallet2.provider)); + + const l2wethToken = deployer.transparentUpgradableProxyContract( + process.env.CONTRACTS_L2_WETH_TOKEN_PROXY_ADDR!, + deployWallet2 + ); + console.log("l2wethToken governor: ", await proxyGov(l2wethToken.address, deployWallet2.provider)); + + // L2 Tokens are BeaconProxies + const l2Erc20BeaconAddress: string = await getERC20BeaconAddress(l2ERC20Bridge.address); + const l2Erc20TokenBeacon = UpgradeableBeaconFactory.connect(l2Erc20BeaconAddress, deployWallet2); + + console.log("l2Erc20TokenBeacon governor: ", await l2Erc20TokenBeacon.owner()); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); diff --git a/ethereum/scripts/initialize-bridges.ts b/l1-contracts/scripts/initialize-bridges.ts similarity index 99% rename from ethereum/scripts/initialize-bridges.ts rename to l1-contracts/scripts/initialize-bridges.ts index 98e1feaa6..b42a831a3 100644 --- a/ethereum/scripts/initialize-bridges.ts +++ b/l1-contracts/scripts/initialize-bridges.ts @@ -1,14 +1,14 @@ import { Command } from "commander"; import { ethers, Wallet } from "ethers"; -import { Deployer } from "../src.ts/deploy"; import { formatUnits, parseUnits } from "ethers/lib/utils"; +import { Deployer } from "../src.ts/deploy"; import { - computeL2Create2Address, - web3Provider, - hashL2Bytecode, applyL1ToL2Alias, + computeL2Create2Address, getNumberFromEnv, + hashL2Bytecode, REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + web3Provider, } from "./utils"; import * as fs from "fs"; @@ -18,7 +18,7 @@ const provider = web3Provider(); const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant"); const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); -const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/zksync/artifacts-zk/"); +const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/l2-contracts/artifacts-zk/"); const l2BridgeArtifactsPath = path.join(contractArtifactsPath, "cache-zk/solpp-generated-contracts/bridge/"); diff --git a/ethereum/scripts/initialize-governance.ts b/l1-contracts/scripts/initialize-governance.ts similarity index 100% rename from ethereum/scripts/initialize-governance.ts rename to l1-contracts/scripts/initialize-governance.ts diff --git a/ethereum/scripts/initialize-l2-weth-token.ts b/l1-contracts/scripts/initialize-l2-weth-token.ts similarity index 96% rename from ethereum/scripts/initialize-l2-weth-token.ts rename to l1-contracts/scripts/initialize-l2-weth-token.ts index b3c7e815b..d7076de23 100644 --- a/ethereum/scripts/initialize-l2-weth-token.ts +++ b/l1-contracts/scripts/initialize-l2-weth-token.ts @@ -1,8 +1,8 @@ import { Command } from "commander"; import { ethers, Wallet } from "ethers"; -import { Deployer } from "../src.ts/deploy"; import { formatUnits, parseUnits } from "ethers/lib/utils"; -import { web3Provider, getNumberFromEnv, getTokens, REQUIRED_L2_GAS_PRICE_PER_PUBDATA } from "./utils"; +import { Deployer } from "../src.ts/deploy"; +import { getNumberFromEnv, getTokens, REQUIRED_L2_GAS_PRICE_PER_PUBDATA, web3Provider } from "./utils"; import * as fs from "fs"; import * as path from "path"; @@ -11,7 +11,7 @@ const provider = web3Provider(); const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant"); const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); -const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/zksync/artifacts-zk/"); +const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/l2-contracts/artifacts-zk/"); const l2BridgeArtifactsPath = path.join(contractArtifactsPath, "cache-zk/solpp-generated-contracts/bridge/"); const openzeppelinTransparentProxyArtifactsPath = path.join( contractArtifactsPath, @@ -116,7 +116,7 @@ async function main() { gasPrice ); console.log(JSON.stringify(l1TxInfo, null, 4)); - console.log("IMPORTANT: gasPrice that you provide in the transaction should <= to the one provided above."); + console.log("IMPORTANT: gasPrice that you provide in the transaction should be <= to the one provided above."); }); program diff --git a/ethereum/scripts/initialize-validator.ts b/l1-contracts/scripts/initialize-validator.ts similarity index 100% rename from ethereum/scripts/initialize-validator.ts rename to l1-contracts/scripts/initialize-validator.ts diff --git a/ethereum/scripts/initialize-weth-bridges.ts b/l1-contracts/scripts/initialize-weth-bridges.ts similarity index 96% rename from ethereum/scripts/initialize-weth-bridges.ts rename to l1-contracts/scripts/initialize-weth-bridges.ts index 69843ddbd..1f14775ff 100644 --- a/ethereum/scripts/initialize-weth-bridges.ts +++ b/l1-contracts/scripts/initialize-weth-bridges.ts @@ -1,8 +1,8 @@ import { Command } from "commander"; import { ethers, Wallet } from "ethers"; -import { Deployer } from "../src.ts/deploy"; import { formatUnits, parseUnits } from "ethers/lib/utils"; -import { web3Provider, applyL1ToL2Alias, getNumberFromEnv, REQUIRED_L2_GAS_PRICE_PER_PUBDATA } from "./utils"; +import { Deployer } from "../src.ts/deploy"; +import { applyL1ToL2Alias, getNumberFromEnv, REQUIRED_L2_GAS_PRICE_PER_PUBDATA, web3Provider } from "./utils"; import * as fs from "fs"; import * as path from "path"; @@ -11,7 +11,7 @@ const provider = web3Provider(); const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant"); const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); -const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/zksync/artifacts-zk/"); +const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/l2-contracts/artifacts-zk/"); const l2BridgeArtifactsPath = path.join(contractArtifactsPath, "cache-zk/solpp-generated-contracts/bridge/"); const openzeppelinTransparentProxyArtifactsPath = path.join( diff --git a/l1-contracts/scripts/migrate-governance.ts b/l1-contracts/scripts/migrate-governance.ts new file mode 100644 index 000000000..aa4f38153 --- /dev/null +++ b/l1-contracts/scripts/migrate-governance.ts @@ -0,0 +1,236 @@ +/// Temporary script that generated the needed calldata for the migration of the governance. + +import { Command } from "commander"; +import { BigNumber, ethers, Wallet } from "ethers"; +import { formatUnits, parseUnits } from "ethers/lib/utils"; +import * as fs from "fs"; +import * as hre from "hardhat"; +import { Deployer } from "../src.ts/deploy"; +import { applyL1ToL2Alias, getAddressFromEnv, getNumberFromEnv, web3Provider } from "./utils"; + +import { getL1TxInfo } from "../../l2-contracts/src/utils"; + +import { Provider } from "zksync-web3"; +import { UpgradeableBeaconFactory } from "../../l2-contracts/typechain/UpgradeableBeaconFactory"; + +const provider = web3Provider(); +const priorityTxMaxGasLimit = BigNumber.from(getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT")); + +const L2ERC20BridgeABI = JSON.parse( + fs + .readFileSync( + "../l2-contracts/artifacts-zk/cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol/L2ERC20Bridge.json" + ) + .toString() +).abi; + +interface TxInfo { + data: string; + to: string; + value?: string; +} + +async function getERC20BeaconAddress(l2Erc20BridgeAddress: string) { + const provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + const contract = new ethers.Contract(l2Erc20BridgeAddress, L2ERC20BridgeABI, provider); + return await contract.l2TokenBeacon(); +} + +function displayTx(msg: string, info: TxInfo) { + console.log(msg); + console.log(JSON.stringify(info, null, 2), "\n"); +} + +async function main() { + const program = new Command(); + + program.version("0.1.0").name("migrate-governance"); + + program + .option("--new-governance-address ") + .option("--gas-price ") + .option("--refund-recipient ") + .action(async (cmd) => { + const gasPrice = cmd.gasPrice ? parseUnits(cmd.gasPrice, "gwei") : await provider.getGasPrice(); + console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); + + const refundRecipient = cmd.refundRecipient; + console.log(`Using refund recipient: ${refundRecipient}`); + + // This action is very dangerous, and so we double check that the governance in env is the same + // one as the user provided manually. + const governanceAddressFromEnv = getAddressFromEnv("CONTRACTS_GOVERNANCE_ADDR").toLowerCase(); + const userProvidedAddress = cmd.newGovernanceAddress.toLowerCase(); + + console.log(`Using governance address from env: ${governanceAddressFromEnv}`); + console.log(`Using governance address from user: ${userProvidedAddress}`); + + if (governanceAddressFromEnv !== userProvidedAddress) { + throw new Error("Governance mismatch"); + } + + // We won't be making any transactions with this wallet, we just need + // it to initialize the Deployer object. + const deployWallet = Wallet.createRandom().connect( + new ethers.providers.JsonRpcProvider(process.env.ETH_CLIENT_WEB3_URL!) + ); + const deployer = new Deployer({ + deployWallet, + verbose: true, + }); + + const expectedDeployedBytecode = hre.artifacts.readArtifactSync("Governance").deployedBytecode; + + const isBytecodeCorrect = + (await provider.getCode(userProvidedAddress)).toLowerCase() === expectedDeployedBytecode.toLowerCase(); + if (!isBytecodeCorrect) { + throw new Error("The address does not contain governance bytecode"); + } + + console.log("Firstly, the current governor should transfer its ownership to the new governance contract."); + console.log("All the transactions below can be executed in one batch"); + + // Step 1. Transfer ownership of all the contracts to the new governor. + + // Below we are preparing the calldata for the L1 transactions + const zkSync = deployer.zkSyncContract(deployWallet); + const validatorTimelock = deployer.validatorTimelock(deployWallet); + + const l1Erc20Bridge = deployer.transparentUpgradableProxyContract( + deployer.addresses.Bridges.ERC20BridgeProxy, + deployWallet + ); + + const erc20MigrationTx = l1Erc20Bridge.interface.encodeFunctionData("changeAdmin", [governanceAddressFromEnv]); + displayTx("L1 ERC20 bridge migration calldata:", { + data: erc20MigrationTx, + to: l1Erc20Bridge.address, + }); + + const zkSyncSetPendingGovernor = zkSync.interface.encodeFunctionData("setPendingGovernor", [ + governanceAddressFromEnv, + ]); + displayTx("zkSync Diamond Proxy migration calldata:", { + data: zkSyncSetPendingGovernor, + to: zkSync.address, + }); + + const validatorTimelockMigration = validatorTimelock.interface.encodeFunctionData("transferOwnership", [ + governanceAddressFromEnv, + ]); + displayTx("Validator timelock migration calldata:", { + data: validatorTimelockMigration, + to: validatorTimelock.address, + }); + + // Below, we prepare the transactions to migrate the L2 contracts. + + // Note that since these are L2 contracts, the governance must be aliased. + const aliasedNewGovernor = applyL1ToL2Alias(governanceAddressFromEnv); + + // L2 ERC20 bridge as well as Weth token are a transparent upgradable proxy. + const l2ERC20Bridge = deployer.transparentUpgradableProxyContract( + process.env.CONTRACTS_L2_ERC20_BRIDGE_ADDR!, + deployWallet + ); + const l2Erc20BridgeCalldata = l2ERC20Bridge.interface.encodeFunctionData("changeAdmin", [aliasedNewGovernor]); + const l2TxForErc20Bridge = await getL1TxInfo( + deployer, + l2ERC20Bridge.address, + l2Erc20BridgeCalldata, + refundRecipient, + gasPrice, + priorityTxMaxGasLimit, + provider + ); + displayTx("L2 ERC20 bridge changeAdmin: ", l2TxForErc20Bridge); + + const l2wethToken = deployer.transparentUpgradableProxyContract( + process.env.CONTRACTS_L2_WETH_TOKEN_PROXY_ADDR!, + deployWallet + ); + const l2WethUpgradeCalldata = l2wethToken.interface.encodeFunctionData("changeAdmin", [aliasedNewGovernor]); + const l2TxForWethUpgrade = await getL1TxInfo( + deployer, + l2wethToken.address, + l2WethUpgradeCalldata, + refundRecipient, + gasPrice, + priorityTxMaxGasLimit, + provider + ); + displayTx("L2 Weth upgrade: ", l2TxForWethUpgrade); + + // L2 Tokens are BeaconProxies + const l2Erc20BeaconAddress: string = await getERC20BeaconAddress(l2ERC20Bridge.address); + const l2Erc20TokenBeacon = UpgradeableBeaconFactory.connect(l2Erc20BeaconAddress, deployWallet); + const l2Erc20BeaconCalldata = l2Erc20TokenBeacon.interface.encodeFunctionData("transferOwnership", [ + aliasedNewGovernor, + ]); + const l2TxForErc20BeaconUpgrade = await getL1TxInfo( + deployer, + l2Erc20BeaconAddress, + l2Erc20BeaconCalldata, + refundRecipient, + gasPrice, + priorityTxMaxGasLimit, + provider + ); + displayTx("L2 ERC20 beacon upgrade: ", l2TxForErc20BeaconUpgrade); + + // Small delimeter for better readability. + console.log("\n\n\n", "-".repeat(20), "\n\n\n"); + + console.log("Secondly, the new governor needs to accept all the roles where they need to be accepted."); + + // Step 2. Accept the roles on L1. Transparent proxy and Beacon proxy contracts do NOT require accepting new ownership. + // However, the following do require: + // - zkSync Diamond Proxy + // - ValidatorTimelock. + + const calls = [ + { + target: zkSync.address, + value: 0, + data: zkSync.interface.encodeFunctionData("acceptGovernor"), + }, + { + target: validatorTimelock.address, + value: 0, + data: validatorTimelock.interface.encodeFunctionData("acceptOwnership"), + }, + ]; + + const operation = { + calls: calls, + predecessor: ethers.constants.HashZero, + salt: ethers.constants.HashZero, + }; + + const governance = deployer.governanceContract(deployWallet); + + const scheduleTransparentCalldata = governance.interface.encodeFunctionData("scheduleTransparent", [ + operation, + 0, + ]); + displayTx("Schedule transparent calldata:\n", { + data: scheduleTransparentCalldata, + to: governance.address, + }); + + const executeCalldata = governance.interface.encodeFunctionData("execute", [operation]); + displayTx("Execute calldata:\n", { + data: executeCalldata, + to: governance.address, + }); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); diff --git a/ethereum/scripts/read-variable.ts b/l1-contracts/scripts/read-variable.ts similarity index 100% rename from ethereum/scripts/read-variable.ts rename to l1-contracts/scripts/read-variable.ts diff --git a/ethereum/scripts/revert-reason.ts b/l1-contracts/scripts/revert-reason.ts similarity index 100% rename from ethereum/scripts/revert-reason.ts rename to l1-contracts/scripts/revert-reason.ts diff --git a/ethereum/scripts/token-info.ts b/l1-contracts/scripts/token-info.ts similarity index 100% rename from ethereum/scripts/token-info.ts rename to l1-contracts/scripts/token-info.ts diff --git a/ethereum/scripts/upgrades/upgrade-1.ts b/l1-contracts/scripts/upgrades/upgrade-1.ts similarity index 100% rename from ethereum/scripts/upgrades/upgrade-1.ts rename to l1-contracts/scripts/upgrades/upgrade-1.ts diff --git a/ethereum/scripts/upgrades/upgrade-2.ts b/l1-contracts/scripts/upgrades/upgrade-2.ts similarity index 100% rename from ethereum/scripts/upgrades/upgrade-2.ts rename to l1-contracts/scripts/upgrades/upgrade-2.ts diff --git a/ethereum/scripts/upgrades/upgrade-3.ts b/l1-contracts/scripts/upgrades/upgrade-3.ts similarity index 100% rename from ethereum/scripts/upgrades/upgrade-3.ts rename to l1-contracts/scripts/upgrades/upgrade-3.ts diff --git a/ethereum/scripts/upgrades/upgrade-4.ts b/l1-contracts/scripts/upgrades/upgrade-4.ts similarity index 100% rename from ethereum/scripts/upgrades/upgrade-4.ts rename to l1-contracts/scripts/upgrades/upgrade-4.ts diff --git a/ethereum/scripts/upgrades/upgrade-5.ts b/l1-contracts/scripts/upgrades/upgrade-5.ts similarity index 100% rename from ethereum/scripts/upgrades/upgrade-5.ts rename to l1-contracts/scripts/upgrades/upgrade-5.ts diff --git a/ethereum/scripts/upgrades/upgrade-6.ts b/l1-contracts/scripts/upgrades/upgrade-6.ts similarity index 100% rename from ethereum/scripts/upgrades/upgrade-6.ts rename to l1-contracts/scripts/upgrades/upgrade-6.ts diff --git a/ethereum/scripts/utils.ts b/l1-contracts/scripts/utils.ts similarity index 83% rename from ethereum/scripts/utils.ts rename to l1-contracts/scripts/utils.ts index 7afd343a0..1b45c3540 100644 --- a/ethereum/scripts/utils.ts +++ b/l1-contracts/scripts/utils.ts @@ -11,18 +11,6 @@ export const L1_TO_L2_ALIAS_OFFSET = "0x1111000000000000000000000000000000001111 // eslint-disable-next-line @typescript-eslint/no-var-requires export const REQUIRED_L2_GAS_PRICE_PER_PUBDATA = require("../../SystemConfig.json").REQUIRED_L2_GAS_PRICE_PER_PUBDATA; -export interface PermissionToCall { - caller: string; - target: string; - functionName: string; - enable: boolean; -} - -export interface AccessMode { - target: string; - mode: number; -} - export function web3Url() { return process.env.ETH_CLIENT_WEB3_URL.split(",")[0] as string; } @@ -77,14 +65,14 @@ export function applyL1ToL2Alias(address: string): string { } export function readBatchBootloaderBytecode() { - const bootloaderPath = path.join(process.env.ZKSYNC_HOME as string, "etc/system-contracts/bootloader"); - return fs.readFileSync(`${bootloaderPath}/build/artifacts/proved_batch.yul/proved_batch.yul.zbin`); + const bootloaderPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/system-contracts/bootloader"); + return fs.readFileSync(`${bootloaderPath}/build/artifacts/proved_batch.yul.zbin`); } export function readSystemContractsBytecode(fileName: string) { - const systemContractsPath = path.join(process.env.ZKSYNC_HOME as string, "etc/system-contracts"); + const systemContractsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/system-contracts"); const artifact = fs.readFileSync( - `${systemContractsPath}/artifacts-zk/cache-zk/solpp-generated-contracts/${fileName}.sol/${fileName}.json` + `${systemContractsPath}/artifacts-zk/contracts-preprocessed/${fileName}.sol/${fileName}.json` ); return JSON.parse(artifact.toString()).bytecode; } @@ -148,24 +136,6 @@ export function getLowerCaseAddress(address: string) { return ethers.utils.getAddress(address).toLowerCase(); } -export function permissionToCallComparator(first: PermissionToCall, second: PermissionToCall) { - if (getLowerCaseAddress(first.caller) < getLowerCaseAddress(second.caller)) { - return -1; - } - if (getLowerCaseAddress(first.caller) > getLowerCaseAddress(second.caller)) { - return 1; - } - - if (getLowerCaseAddress(first.target) < getLowerCaseAddress(second.target)) { - return -1; - } - if (getLowerCaseAddress(first.target) > getLowerCaseAddress(second.target)) { - return 1; - } - - return first.functionName.localeCompare(second.functionName); -} - export type L1Token = { name: string; symbol: string; diff --git a/ethereum/scripts/verify.ts b/l1-contracts/scripts/verify.ts similarity index 96% rename from ethereum/scripts/verify.ts rename to l1-contracts/scripts/verify.ts index 26d599d90..f359f4697 100644 --- a/ethereum/scripts/verify.ts +++ b/l1-contracts/scripts/verify.ts @@ -54,10 +54,7 @@ async function main() { // } // Bridges - const promise = verifyPromise(addresses.Bridges.ERC20BridgeImplementation, [ - addresses.ZkSync.DiamondProxy, - addresses.AllowList, - ]); + const promise = verifyPromise(addresses.Bridges.ERC20BridgeImplementation, [addresses.ZkSync.DiamondProxy]); promises.push(promise); const messages = await Promise.allSettled(promises); diff --git a/ethereum/src.ts/deploy-utils.ts b/l1-contracts/src.ts/deploy-utils.ts similarity index 100% rename from ethereum/src.ts/deploy-utils.ts rename to l1-contracts/src.ts/deploy-utils.ts diff --git a/ethereum/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts similarity index 95% rename from ethereum/src.ts/deploy.ts rename to l1-contracts/src.ts/deploy.ts index a00c16b1e..22416fbe4 100644 --- a/ethereum/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -10,7 +10,6 @@ import { L1ERC20BridgeFactory } from "../typechain/L1ERC20BridgeFactory"; import { L1WethBridgeFactory } from "../typechain/L1WethBridgeFactory"; import { ValidatorTimelockFactory } from "../typechain/ValidatorTimelockFactory"; import { SingletonFactoryFactory } from "../typechain/SingletonFactoryFactory"; -import { AllowListFactory } from "../typechain"; import { TransparentUpgradeableProxyFactory } from "../typechain/TransparentUpgradeableProxyFactory"; import { readSystemContractsBytecode, @@ -46,7 +45,6 @@ export interface DeployedAddresses { WethBridgeProxy: string; }; Governance: string; - AllowList: string; ValidatorTimeLock: string; Create2Factory: string; } @@ -76,7 +74,6 @@ export function deployedAddressesFromEnv(): DeployedAddresses { WethBridgeImplementation: getAddressFromEnv("CONTRACTS_L1_WETH_BRIDGE_IMPL_ADDR"), WethBridgeProxy: getAddressFromEnv("CONTRACTS_L1_WETH_BRIDGE_PROXY_ADDR"), }, - AllowList: getAddressFromEnv("CONTRACTS_L1_ALLOW_LIST_ADDR"), Create2Factory: getAddressFromEnv("CONTRACTS_CREATE2_FACTORY_ADDR"), ValidatorTimeLock: getAddressFromEnv("CONTRACTS_VALIDATOR_TIMELOCK_ADDR"), Governance: getAddressFromEnv("CONTRACTS_GOVERNANCE_ADDR"), @@ -133,7 +130,6 @@ export class Deployer { genesisBatchHash, genesisIndexRepeatedStorageChanges, genesisBatchCommitment, - allowList: this.addresses.AllowList, verifierParams, zkPorterIsAvailable: false, l2BootloaderBytecodeHash: L2_BOOTLOADER_BYTECODE_HASH, @@ -206,17 +202,6 @@ export class Deployer { this.addresses.Governance = contractAddress; } - public async deployAllowList(create2Salt: string, ethTxOptions: ethers.providers.TransactionRequest) { - ethTxOptions.gasLimit ??= 10_000_000; - const contractAddress = await this.deployViaCreate2("AllowList", [this.ownerAddress], create2Salt, ethTxOptions); - - if (this.verbose) { - console.log(`CONTRACTS_L1_ALLOW_LIST_ADDR=${contractAddress}`); - } - - this.addresses.AllowList = contractAddress; - } - public async deployMailboxFacet(create2Salt: string, ethTxOptions: ethers.providers.TransactionRequest) { ethTxOptions.gasLimit ??= 10_000_000; const contractAddress = await this.deployViaCreate2("MailboxFacet", [], create2Salt, ethTxOptions); @@ -276,7 +261,7 @@ export class Deployer { ethTxOptions.gasLimit ??= 10_000_000; const contractAddress = await this.deployViaCreate2( "L1ERC20Bridge", - [this.addresses.ZkSync.DiamondProxy, this.addresses.AllowList], + [this.addresses.ZkSync.DiamondProxy], create2Salt, ethTxOptions ); @@ -320,7 +305,7 @@ export class Deployer { ethTxOptions.gasLimit ??= 10_000_000; const contractAddress = await this.deployViaCreate2( "L1WethBridge", - [l1WethToken, this.addresses.ZkSync.DiamondProxy, this.addresses.AllowList], + [l1WethToken, this.addresses.ZkSync.DiamondProxy], create2Salt, ethTxOptions ); @@ -487,10 +472,6 @@ export class Deployer { return ValidatorTimelockFactory.connect(this.addresses.ValidatorTimeLock, signerOrProvider); } - public l1AllowList(signerOrProvider: Signer | providers.Provider) { - return AllowListFactory.connect(this.addresses.AllowList, signerOrProvider); - } - public defaultERC20Bridge(signerOrProvider: Signer | providers.Provider) { return L1ERC20BridgeFactory.connect(this.addresses.Bridges.ERC20BridgeProxy, signerOrProvider); } diff --git a/ethereum/src.ts/diamondCut.ts b/l1-contracts/src.ts/diamondCut.ts similarity index 100% rename from ethereum/src.ts/diamondCut.ts rename to l1-contracts/src.ts/diamondCut.ts diff --git a/l1-contracts/test/foundry/unit/concrete/Admin/Authorization.t.sol b/l1-contracts/test/foundry/unit/concrete/Admin/Authorization.t.sol new file mode 100644 index 000000000..f390a62d4 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/Admin/Authorization.t.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {AdminTest} from "./_Admin_Shared.t.sol"; + +contract AuthorizationTest is AdminTest { + function test_SetPendingAdmin_RevertWhen_AdminNotGovernanceOwner() public { + address newAdmin = address(0x1337); + vm.prank(owner); + vm.expectRevert(bytes.concat("1g")); + proxyAsAdmin.setPendingAdmin(newAdmin); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/Admin/_Admin_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Admin/_Admin_Shared.t.sol new file mode 100644 index 000000000..3a3a96301 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/Admin/_Admin_Shared.t.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {Test} from "forge-std/Test.sol"; +import {DiamondProxy} from "solpp/zksync/DiamondProxy.sol"; +import {DiamondInit} from "solpp/zksync/DiamondInit.sol"; +import {VerifierParams} from "solpp/zksync/Storage.sol"; +import {Diamond} from "solpp/zksync/libraries/Diamond.sol"; +import {AdminFacet} from "solpp/zksync/facets/Admin.sol"; +import {Governance} from "solpp/governance/Governance.sol"; + +contract AdminTest is Test { + DiamondProxy internal diamondProxy; + address internal owner; + address internal securityCouncil; + address internal governor; + AdminFacet internal adminFacet; + AdminFacet internal proxyAsAdmin; + + function getAdminSelectors() private view returns (bytes4[] memory) { + bytes4[] memory dcSelectors = new bytes4[](10); + dcSelectors[0] = adminFacet.setPendingGovernor.selector; + dcSelectors[1] = adminFacet.acceptGovernor.selector; + dcSelectors[2] = adminFacet.setPendingAdmin.selector; + dcSelectors[3] = adminFacet.acceptAdmin.selector; + dcSelectors[4] = adminFacet.setValidator.selector; + dcSelectors[5] = adminFacet.setPorterAvailability.selector; + dcSelectors[6] = adminFacet.setPriorityTxMaxGasLimit.selector; + dcSelectors[7] = adminFacet.executeUpgrade.selector; + dcSelectors[8] = adminFacet.freezeDiamond.selector; + dcSelectors[9] = adminFacet.unfreezeDiamond.selector; + return dcSelectors; + } + + function setUp() public { + owner = makeAddr("owner"); + securityCouncil = makeAddr("securityCouncil"); + governor = makeAddr("governor"); + DiamondInit diamondInit = new DiamondInit(); + + VerifierParams memory dummyVerifierParams = VerifierParams({ + recursionNodeLevelVkHash: 0, + recursionLeafLevelVkHash: 0, + recursionCircuitsSetVksHash: 0 + }); + + adminFacet = new AdminFacet(); + + bytes memory diamondInitCalldata = abi.encodeWithSelector( + diamondInit.initialize.selector, + 0x03752D8252d67f99888E741E3fB642803B29B155, + governor, + owner, + 0x02c775f0a90abf7a0e8043f2fdc38f0580ca9f9996a895d05a501bfeaa3b2e21, + 0, + 0x0000000000000000000000000000000000000000000000000000000000000000, + dummyVerifierParams, + false, + 0x0100000000000000000000000000000000000000000000000000000000000000, + 0x0100000000000000000000000000000000000000000000000000000000000000, + 500000, // priority tx max L2 gas limit + 0 + ); + + Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](1); + facetCuts[0] = Diamond.FacetCut({ + facet: address(adminFacet), + action: Diamond.Action.Add, + isFreezable: false, + selectors: getAdminSelectors() + }); + + Diamond.DiamondCutData memory diamondCutData = Diamond.DiamondCutData({ + facetCuts: facetCuts, + initAddress: address(diamondInit), + initCalldata: diamondInitCalldata + }); + + diamondProxy = new DiamondProxy(block.chainid, diamondCutData); + proxyAsAdmin = AdminFacet(address(diamondProxy)); + } +} diff --git a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/ClaimFailedDeposit.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/ClaimFailedDeposit.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/ClaimFailedDeposit.t.sol rename to l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/ClaimFailedDeposit.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/Deposit.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/Deposit.t.sol similarity index 85% rename from ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/Deposit.t.sol rename to l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/Deposit.t.sol index 0f2e18f76..fc326d95b 100644 --- a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/Deposit.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/Deposit.t.sol @@ -3,19 +3,9 @@ pragma solidity 0.8.20; import {L1WethBridgeTest} from "./_L1WethBridge_Shared.t.sol"; -import {IAllowList} from "../../../../../../cache/solpp-generated-contracts/common/interfaces/IAllowList.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "../../../../../../cache/solpp-generated-contracts/zksync/Config.sol"; contract DepositTest is L1WethBridgeTest { - function test_RevertWhen_UnWhitelistedAddressDeposits() public { - vm.prank(owner); - allowList.setAccessMode(address(bridgeProxy), IAllowList.AccessMode.Closed); - - vm.prank(randomSigner); - vm.expectRevert(bytes.concat("nr")); - bridgeProxy.deposit(randomSigner, address(0), 0, 0, 0, address(0)); - } - function test_RevertWhen_ReceivedL1TokenIsNotL1WethAddress() public { vm.expectRevert("Invalid L1 token address"); bridgeProxy.deposit(randomSigner, makeAddr("invalidL1TokenAddress"), 0, 0, 0, address(0)); diff --git a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/FinalizeWithdrawal.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/FinalizeWithdrawal.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/FinalizeWithdrawal.t.sol rename to l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/FinalizeWithdrawal.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/L2TokenAddress.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/L2TokenAddress.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/L2TokenAddress.t.sol rename to l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/L2TokenAddress.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/Receive.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/Receive.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/Receive.t.sol rename to l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/Receive.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/_L1WethBridge_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/_L1WethBridge_Shared.t.sol similarity index 87% rename from ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/_L1WethBridge_Shared.t.sol rename to l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/_L1WethBridge_Shared.t.sol index 13a1a8296..5167c6527 100644 --- a/ethereum/test/foundry/unit/concrete/Bridge/L1WethBridge/_L1WethBridge_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridge/L1WethBridge/_L1WethBridge_Shared.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.20; import {Test} from "forge-std/Test.sol"; -import {AllowList} from "../../../../../../cache/solpp-generated-contracts/common/AllowList.sol"; import {L1WethBridge} from "../../../../../../cache/solpp-generated-contracts/bridge/L1WethBridge.sol"; import {WETH9} from "../../../../../../cache/solpp-generated-contracts/dev-contracts/WETH9.sol"; import {GettersFacet} from "../../../../../../cache/solpp-generated-contracts/zksync/facets/Getters.sol"; @@ -12,7 +11,6 @@ import {DiamondInit} from "../../../../../../cache/solpp-generated-contracts/zks import {VerifierParams} from "../../../../../../cache/solpp-generated-contracts/zksync/Storage.sol"; import {Diamond} from "../../../../../../cache/solpp-generated-contracts/zksync/libraries/Diamond.sol"; import {DiamondProxy} from "../../../../../../cache/solpp-generated-contracts/zksync/DiamondProxy.sol"; -import {IAllowList} from "../../../../../../cache/solpp-generated-contracts/common/interfaces/IAllowList.sol"; import {Utils} from "../../Utils/Utils.sol"; import {IZkSync} from "../../../../../../cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; @@ -20,7 +18,6 @@ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.s contract L1WethBridgeTest is Test { address internal owner; address internal randomSigner; - AllowList internal allowList; L1WethBridge internal bridgeProxy; WETH9 internal l1Weth; bytes4 internal functionSignature = 0x6c0960f9; @@ -31,7 +28,6 @@ contract L1WethBridgeTest is Test { GettersFacet gettersFacet = new GettersFacet(); MailboxFacet mailboxFacet = new MailboxFacet(); - allowList = new AllowList(owner); DiamondInit diamondInit = new DiamondInit(); bytes8 dummyHash = 0x1234567890123456; @@ -44,7 +40,6 @@ contract L1WethBridgeTest is Test { 0, 0, 0, - allowList, VerifierParams({recursionNodeLevelVkHash: 0, recursionLeafLevelVkHash: 0, recursionCircuitsSetVksHash: 0}), false, dummyHash, @@ -76,14 +71,11 @@ contract L1WethBridgeTest is Test { uint256 chainId = block.chainid; DiamondProxy diamondProxy = new DiamondProxy(chainId, diamondCutData); - vm.prank(owner); - allowList.setAccessMode(address(diamondProxy), IAllowList.AccessMode.Public); - l1Weth = new WETH9(); IZkSync zkSync = IZkSync(address(diamondProxy)); - L1WethBridge bridge = new L1WethBridge(payable(address(l1Weth)), zkSync, allowList); + L1WethBridge bridge = new L1WethBridge(payable(address(l1Weth)), zkSync); bytes memory garbageBytecode = abi.encodePacked( bytes32(0x1111111111111111111111111111111111111111111111111111111111111111) @@ -105,8 +97,5 @@ contract L1WethBridgeTest is Test { ERC1967Proxy x = new ERC1967Proxy{value: 2000000000000000000}(address(bridge), bridgeInitData); bridgeProxy = L1WethBridge(payable(address(x))); - - vm.prank(owner); - allowList.setAccessMode(address(bridgeProxy), IAllowList.AccessMode.Public); } } diff --git a/ethereum/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol rename to l1-contracts/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol diff --git a/ethereum/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol rename to l1-contracts/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol diff --git a/ethereum/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol similarity index 99% rename from ethereum/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol rename to l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol index fcc1fd7b7..3b1e35c24 100644 --- a/ethereum/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol @@ -76,7 +76,6 @@ contract UpgradeLogicTest is DiamondCutTest { 0x02c775f0a90abf7a0e8043f2fdc38f0580ca9f9996a895d05a501bfeaa3b2e21, 0, 0x0000000000000000000000000000000000000000000000000000000000000000, - 0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55, dummyVerifierParams, false, 0x0100000000000000000000000000000000000000000000000000000000000000, diff --git a/ethereum/test/foundry/unit/concrete/DiamondCut/_DiamondCut_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/_DiamondCut_Shared.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/DiamondCut/_DiamondCut_Shared.t.sol rename to l1-contracts/test/foundry/unit/concrete/DiamondCut/_DiamondCut_Shared.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Executor/Authorization.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Authorization.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Executor/Authorization.t.sol rename to l1-contracts/test/foundry/unit/concrete/Executor/Authorization.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Executor/Committing.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Committing.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Executor/Committing.t.sol rename to l1-contracts/test/foundry/unit/concrete/Executor/Committing.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Executor/Executing.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Executing.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Executor/Executing.t.sol rename to l1-contracts/test/foundry/unit/concrete/Executor/Executing.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Executor/Proving.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Proving.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Executor/Proving.t.sol rename to l1-contracts/test/foundry/unit/concrete/Executor/Proving.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Executor/Reverting.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Reverting.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Executor/Reverting.t.sol rename to l1-contracts/test/foundry/unit/concrete/Executor/Reverting.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol similarity index 88% rename from ethereum/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol rename to l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol index be6dfb3ef..4b6f6edf0 100644 --- a/ethereum/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol @@ -4,8 +4,6 @@ pragma solidity 0.8.20; import {Test} from "forge-std/Test.sol"; import {Utils, DEFAULT_L2_LOGS_TREE_ROOT_HASH} from "../Utils/Utils.sol"; -import {AllowList} from "../../../../../cache/solpp-generated-contracts/common/AllowList.sol"; -import {IAllowList} from "../../../../../cache/solpp-generated-contracts/common/interfaces/IAllowList.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER} from "../../../../../cache/solpp-generated-contracts/zksync/Config.sol"; import {DiamondInit} from "../../../../../cache/solpp-generated-contracts/zksync/DiamondInit.sol"; import {DiamondProxy} from "../../../../../cache/solpp-generated-contracts/zksync/DiamondProxy.sol"; @@ -21,7 +19,6 @@ contract ExecutorTest is Test { address internal owner; address internal validator; address internal randomSigner; - AllowList internal allowList; AdminFacet internal admin; ExecutorFacet internal executor; GettersFacet internal getters; @@ -60,7 +57,7 @@ contract ExecutorTest is Test { } function getGettersSelectors() public view returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](29); + bytes4[] memory selectors = new bytes4[](28); selectors[0] = getters.getVerifier.selector; selectors[1] = getters.getGovernor.selector; selectors[2] = getters.getPendingGovernor.selector; @@ -79,17 +76,16 @@ contract ExecutorTest is Test { selectors[15] = getters.getVerifierParams.selector; selectors[16] = getters.isDiamondStorageFrozen.selector; selectors[17] = getters.getPriorityTxMaxGasLimit.selector; - selectors[18] = getters.getAllowList.selector; - selectors[19] = getters.isEthWithdrawalFinalized.selector; - selectors[20] = getters.facets.selector; - selectors[21] = getters.facetFunctionSelectors.selector; - selectors[22] = getters.facetAddresses.selector; - selectors[23] = getters.facetAddress.selector; - selectors[24] = getters.isFunctionFreezable.selector; - selectors[25] = getters.isFacetFreezable.selector; - selectors[26] = getters.getTotalBatchesCommitted.selector; - selectors[27] = getters.getTotalBatchesVerified.selector; - selectors[28] = getters.getTotalBatchesExecuted.selector; + selectors[18] = getters.isEthWithdrawalFinalized.selector; + selectors[19] = getters.facets.selector; + selectors[20] = getters.facetFunctionSelectors.selector; + selectors[21] = getters.facetAddresses.selector; + selectors[22] = getters.facetAddress.selector; + selectors[23] = getters.isFunctionFreezable.selector; + selectors[24] = getters.isFacetFreezable.selector; + selectors[25] = getters.getTotalBatchesCommitted.selector; + selectors[26] = getters.getTotalBatchesVerified.selector; + selectors[27] = getters.getTotalBatchesExecuted.selector; return selectors; } @@ -114,7 +110,6 @@ contract ExecutorTest is Test { getters = new GettersFacet(); mailbox = new MailboxFacet(); - allowList = new AllowList(owner); DiamondInit diamondInit = new DiamondInit(); bytes8 dummyHash = 0x1234567890123456; @@ -127,7 +122,6 @@ contract ExecutorTest is Test { 0, 0, 0, - allowList, VerifierParams({recursionNodeLevelVkHash: 0, recursionLeafLevelVkHash: 0, recursionCircuitsSetVksHash: 0}), false, dummyHash, @@ -171,9 +165,6 @@ contract ExecutorTest is Test { uint256 chainId = block.chainid; DiamondProxy diamondProxy = new DiamondProxy(chainId, diamondCutData); - vm.prank(owner); - allowList.setAccessMode(address(diamondProxy), IAllowList.AccessMode.Public); - executor = ExecutorFacet(address(diamondProxy)); getters = GettersFacet(address(diamondProxy)); mailbox = MailboxFacet(address(diamondProxy)); diff --git a/ethereum/test/foundry/unit/concrete/Governance/Authorization.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Governance/Authorization.t.sol rename to l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Governance/Executing.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Governance/Executing.t.sol rename to l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Governance/Fallback.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/Fallback.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Governance/Fallback.t.sol rename to l1-contracts/test/foundry/unit/concrete/Governance/Fallback.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Governance/OperationStatus.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/OperationStatus.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Governance/OperationStatus.t.sol rename to l1-contracts/test/foundry/unit/concrete/Governance/OperationStatus.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Governance/Reentrancy.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Governance/Reentrancy.t.sol rename to l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Governance/SelfUpgrades.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/SelfUpgrades.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Governance/SelfUpgrades.t.sol rename to l1-contracts/test/foundry/unit/concrete/Governance/SelfUpgrades.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Governance/_Governance_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/_Governance_Shared.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Governance/_Governance_Shared.t.sol rename to l1-contracts/test/foundry/unit/concrete/Governance/_Governance_Shared.t.sol diff --git a/l1-contracts/test/foundry/unit/concrete/Merkle/Merkle.t.sol b/l1-contracts/test/foundry/unit/concrete/Merkle/Merkle.t.sol new file mode 100644 index 000000000..2ec6591b6 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/Merkle/Merkle.t.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {Test} from "forge-std/Test.sol"; +import {MerkleTest} from "solpp/dev-contracts/test/MerkleTest.sol"; +import {MerkleTreeNoSort} from "./MerkleTreeNoSort.sol"; + +contract MerkleTestTest is Test { + MerkleTreeNoSort merkleTree; + MerkleTest merkleTest; + bytes32[] elements; + bytes32 root; + + function setUp() public { + merkleTree = new MerkleTreeNoSort(); + merkleTest = new MerkleTest(); + + for (uint256 i = 0; i < 65; i++) { + elements.push(keccak256(abi.encodePacked(i))); + } + + root = merkleTree.getRoot(elements); + } + + function testElements(uint256 i) public { + vm.assume(i < elements.length); + bytes32 leaf = elements[i]; + bytes32[] memory proof = merkleTree.getProof(elements, i); + + bytes32 rootFromContract = merkleTest.calculateRoot(proof, i, leaf); + + assertEq(rootFromContract, root); + } + + function testFirstElement() public { + testElements(0); + } + + function testLastElement() public { + testElements(elements.length - 1); + } + + function testEmptyProof_shouldRevert() public { + bytes32 leaf = elements[0]; + bytes32[] memory proof; + + vm.expectRevert(bytes("xc")); + merkleTest.calculateRoot(proof, 0, leaf); + } + + function testLeafIndexTooBig_shouldRevert() public { + bytes32 leaf = elements[0]; + bytes32[] memory proof = merkleTree.getProof(elements, 0); + + vm.expectRevert(bytes("px")); + merkleTest.calculateRoot(proof, 2 ** 255, leaf); + } + + function testProofLengthTooLarge_shouldRevert() public { + bytes32 leaf = elements[0]; + bytes32[] memory proof = new bytes32[](256); + + vm.expectRevert(bytes("bt")); + merkleTest.calculateRoot(proof, 0, leaf); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/Merkle/MerkleTreeNoSort.sol b/l1-contracts/test/foundry/unit/concrete/Merkle/MerkleTreeNoSort.sol new file mode 100644 index 000000000..3f4f64aa4 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/Merkle/MerkleTreeNoSort.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import "murky/common/MurkyBase.sol"; + +contract MerkleTreeNoSort is MurkyBase { + /******************** + * HASHING FUNCTION * + ********************/ + + /// The original Merkle tree contains the ascending sort and concat prior to hashing, so we need to override it + function hashLeafPairs(bytes32 left, bytes32 right) public pure override returns (bytes32 _hash) { + assembly { + mstore(0x0, left) + mstore(0x20, right) + _hash := keccak256(0x0, 0x40) + } + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/PriorityQueue/OnEmptyQueue.sol b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/OnEmptyQueue.sol new file mode 100644 index 000000000..98a0e3e22 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/OnEmptyQueue.sol @@ -0,0 +1,22 @@ +pragma solidity 0.8.20; + +import {PriorityQueueSharedTest} from "./_PriorityQueue_Shared.t.sol"; + +contract OnEmptyQueueTest is PriorityQueueSharedTest { + function test_gets() public { + assertEq(0, priorityQueue.getSize()); + assertEq(0, priorityQueue.getFirstUnprocessedPriorityTx()); + assertEq(0, priorityQueue.getTotalPriorityTxs()); + assertTrue(priorityQueue.isEmpty()); + } + + function test_failGetFront() public { + vm.expectRevert(bytes("D")); + priorityQueue.front(); + } + + function test_failPopFront() public { + vm.expectRevert(bytes("s")); + priorityQueue.popFront(); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/PriorityQueue/PopOperations.sol b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/PopOperations.sol new file mode 100644 index 000000000..c5146838e --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/PopOperations.sol @@ -0,0 +1,71 @@ +pragma solidity 0.8.20; + +import {PriorityQueueSharedTest} from "./_PriorityQueue_Shared.t.sol"; +import {PriorityOperation} from "../../../../../cache/solpp-generated-contracts/dev-contracts/test/PriorityQueueTest.sol"; + +contract PopOperationsTest is PriorityQueueSharedTest { + uint public constant NUMBER_OPERATIONS = 10; + + function setUp() public { + push_mock_entries(NUMBER_OPERATIONS); + } + + function test_after_pop() public { + assertEq(NUMBER_OPERATIONS, priorityQueue.getSize()); + + PriorityOperation memory front = priorityQueue.popFront(); + assertEq(keccak256(abi.encode(0)), front.canonicalTxHash); + assertEq(uint64(0), front.expirationTimestamp); + assertEq(uint192(0), front.layer2Tip); + + assertEq(NUMBER_OPERATIONS - 1, priorityQueue.getSize()); + assertEq(1, priorityQueue.getFirstUnprocessedPriorityTx()); + assertEq(NUMBER_OPERATIONS, priorityQueue.getTotalPriorityTxs()); + assertFalse(priorityQueue.isEmpty()); + + // Ok - one more pop + PriorityOperation memory front2 = priorityQueue.popFront(); + assertEq(keccak256(abi.encode(1)), front2.canonicalTxHash); + assertEq(uint64(1), front2.expirationTimestamp); + assertEq(uint192(1), front2.layer2Tip); + + assertEq(NUMBER_OPERATIONS - 2, priorityQueue.getSize()); + assertEq(2, priorityQueue.getFirstUnprocessedPriorityTx()); + assertEq(NUMBER_OPERATIONS, priorityQueue.getTotalPriorityTxs()); + assertFalse(priorityQueue.isEmpty()); + } + + function test_pop_until_limit() public { + for (uint i = 0; i < NUMBER_OPERATIONS; ++i) { + PriorityOperation memory front = priorityQueue.popFront(); + assertEq(keccak256(abi.encode(i)), front.canonicalTxHash); + } + + assertEq(0, priorityQueue.getSize()); + assertEq(NUMBER_OPERATIONS, priorityQueue.getFirstUnprocessedPriorityTx()); + assertEq(NUMBER_OPERATIONS, priorityQueue.getTotalPriorityTxs()); + assertTrue(priorityQueue.isEmpty()); + + // And now let's push something. + + PriorityOperation memory dummyOp = PriorityOperation({ + canonicalTxHash: keccak256(abi.encode(300)), + expirationTimestamp: uint64(300), + layer2Tip: uint192(300) + }); + priorityQueue.pushBack(dummyOp); + + assertEq(1, priorityQueue.getSize()); + assertEq(NUMBER_OPERATIONS, priorityQueue.getFirstUnprocessedPriorityTx()); + assertEq(NUMBER_OPERATIONS + 1, priorityQueue.getTotalPriorityTxs()); + assertFalse(priorityQueue.isEmpty()); + + PriorityOperation memory front_end = priorityQueue.popFront(); + assertEq(keccak256(abi.encode(300)), front_end.canonicalTxHash); + assertTrue(priorityQueue.isEmpty()); + + // And now let's go over the limit and fail. + vm.expectRevert(bytes.concat("s")); + priorityQueue.popFront(); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/PriorityQueue/PushOperations.sol b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/PushOperations.sol new file mode 100644 index 000000000..0fb540d00 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/PushOperations.sol @@ -0,0 +1,25 @@ +pragma solidity 0.8.20; + +import {PriorityQueueSharedTest} from "./_PriorityQueue_Shared.t.sol"; +import {PriorityOperation} from "../../../../../cache/solpp-generated-contracts/dev-contracts/test/PriorityQueueTest.sol"; + +contract PushOperationsTest is PriorityQueueSharedTest { + uint public constant NUMBER_OPERATIONS = 10; + + function setUp() public { + push_mock_entries(NUMBER_OPERATIONS); + } + + function test_front() public { + assertEq(NUMBER_OPERATIONS, priorityQueue.getSize()); + PriorityOperation memory front = priorityQueue.front(); + assertEq(keccak256(abi.encode(0)), front.canonicalTxHash); + assertEq(uint64(0), front.expirationTimestamp); + assertEq(uint192(0), front.layer2Tip); + // This is 'front' and not popFront, so the amount should not change. + assertEq(NUMBER_OPERATIONS, priorityQueue.getSize()); + assertEq(0, priorityQueue.getFirstUnprocessedPriorityTx()); + assertEq(NUMBER_OPERATIONS, priorityQueue.getTotalPriorityTxs()); + assertFalse(priorityQueue.isEmpty()); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/PriorityQueue/_PriorityQueue_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/_PriorityQueue_Shared.t.sol new file mode 100644 index 000000000..a219aea17 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/PriorityQueue/_PriorityQueue_Shared.t.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {Test} from "forge-std/Test.sol"; +import {PriorityQueueTest, PriorityOperation} from "solpp/dev-contracts/test/PriorityQueueTest.sol"; + +contract PriorityQueueSharedTest is Test { + PriorityQueueTest internal priorityQueue; + + constructor() { + priorityQueue = new PriorityQueueTest(); + } + + // Pushes 'count' entries into the priority queue. + function push_mock_entries(uint count) public { + for (uint i = 0; i < count; ++i) { + PriorityOperation memory dummyOp = PriorityOperation({ + canonicalTxHash: keccak256(abi.encode(i)), + expirationTimestamp: uint64(i), + layer2Tip: uint192(i) + }); + priorityQueue.pushBack(dummyOp); + } + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/TransactionValidator/ValidateL1L2Tx.t.sol b/l1-contracts/test/foundry/unit/concrete/TransactionValidator/ValidateL1L2Tx.t.sol new file mode 100644 index 000000000..9d3a35523 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/TransactionValidator/ValidateL1L2Tx.t.sol @@ -0,0 +1,64 @@ +pragma solidity 0.8.20; + +import {TransactionValidatorSharedTest} from "./_TransactionValidator_Shared.t.sol"; +import {IMailbox} from "solpp/zksync/interfaces/IMailbox.sol"; +import {TransactionValidator} from "solpp/zksync/libraries/TransactionValidator.sol"; + +contract ValidateL1L2TxTest is TransactionValidatorSharedTest { + function test_BasicRequestL1L2() public pure { + IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction(); + testTx.gasLimit = 500000; + validateL1ToL2Transaction(testTx, 500000); + } + + function test_RevertWhen_GasLimitDoesntCoverOverhead() public { + IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction(); + // The limit is so low, that it doesn't even cover the overhead + testTx.gasLimit = 0; + vm.expectRevert(bytes("my")); + validateL1ToL2Transaction(testTx, 500000); + } + + function test_RevertWhen_GasLimitHigherThanMax() public { + IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction(); + // We should fail, if user asks for too much gas. + // Notice, that we subtract the transaction overhead costs from the user's gas limit + // before checking that it is below the max gas limit. + uint256 priorityTxMaxGasLimit = 500000; + testTx.gasLimit = priorityTxMaxGasLimit + 1000000; + vm.expectRevert(bytes("ui")); + validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit); + } + + function test_RevertWhen_TooMuchPubdata() public { + IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction(); + // We should fail, if user's transaction could output too much pubdata. + // We can allow only 99k of pubdata (otherwise we'd exceed the ethereum calldata limits). + + uint256 priorityTxMaxGasLimit = 500000; + testTx.gasLimit = priorityTxMaxGasLimit; + // So if the pubdata costs per byte is 1 - then this transaction could produce 500k of pubdata. + // (hypothetically, assuming all the gas was spent on writing). + testTx.gasPerPubdataByteLimit = 1; + vm.expectRevert(bytes("uk")); + validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit); + } + + function test_RevertWhen_BelowMinimumCost() public { + IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction(); + uint256 priorityTxMaxGasLimit = 500000; + testTx.gasLimit = 200000; + vm.expectRevert(bytes("up")); + validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit); + } + + function test_RevertWhen_HugePubdata() public { + IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction(); + uint256 priorityTxMaxGasLimit = 500000; + testTx.gasLimit = 400000; + // Setting huge pubdata limit should cause the panic. + testTx.gasPerPubdataByteLimit = type(uint256).max; + vm.expectRevert(); + validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/TransactionValidator/ValidateUpgradeTransaction.t.sol b/l1-contracts/test/foundry/unit/concrete/TransactionValidator/ValidateUpgradeTransaction.t.sol new file mode 100644 index 000000000..14cd4c0eb --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/TransactionValidator/ValidateUpgradeTransaction.t.sol @@ -0,0 +1,100 @@ +pragma solidity 0.8.20; + +import {TransactionValidatorSharedTest} from "./_TransactionValidator_Shared.t.sol"; +import {IMailbox} from "solpp/zksync/interfaces/IMailbox.sol"; +import {TransactionValidator} from "solpp/zksync/libraries/TransactionValidator.sol"; + +contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { + function test_BasicRequest() public pure { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_RequestNotFromSystemContract() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // only system contracts (address < 2^16) are allowed to send upgrade transactions. + testTx.from = uint256(1000000000); + vm.expectRevert(bytes("ua")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_RequestNotToSystemContract() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // Now the 'to' address it too large. + testTx.to = uint256(type(uint160).max) + 100; + vm.expectRevert(bytes("ub")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_PaymasterIsNotZero() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // Paymaster must be 0 - otherwise we revert. + testTx.paymaster = 1; + vm.expectRevert(bytes("uc")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_ValueIsNotZero() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // Value must be 0 - otherwise we revert. + testTx.value = 1; + vm.expectRevert(bytes("ud")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_Reserved0IsNonZero() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // reserved 0 must be 0 - otherwise we revert. + testTx.reserved[0] = 1; + vm.expectRevert(bytes("ue")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_Reserved1IsTooLarge() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // reserved 1 must be a valid address + testTx.reserved[1] = uint256(type(uint160).max) + 100; + vm.expectRevert(bytes("uf")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_Reserved2IsNonZero() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // reserved 2 must be 0 - otherwise we revert. + testTx.reserved[2] = 1; + vm.expectRevert(bytes("ug")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_Reserved3IsNonZero() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // reserved 3 be 0 - otherwise we revert. + testTx.reserved[3] = 1; + vm.expectRevert(bytes("uo")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_NonZeroSignature() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // Signature must be 0 - otherwise we revert. + testTx.signature = bytes("hello"); + vm.expectRevert(bytes("uh")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_PaymasterInputNonZero() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // PaymasterInput must be 0 - otherwise we revert. + testTx.paymasterInput = bytes("hi"); + vm.expectRevert(bytes("ul")); + TransactionValidator.validateUpgradeTransaction(testTx); + } + + function test_RevertWhen_ReservedDynamicIsNonZero() public { + IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction(); + // ReservedDynamic must be 0 - otherwise we revert. + testTx.reservedDynamic = bytes("something"); + vm.expectRevert(bytes("um")); + TransactionValidator.validateUpgradeTransaction(testTx); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/TransactionValidator/_TransactionValidator_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/TransactionValidator/_TransactionValidator_Shared.t.sol new file mode 100644 index 000000000..cd728d680 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/TransactionValidator/_TransactionValidator_Shared.t.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {Test} from "forge-std/Test.sol"; +import {IMailbox} from "solpp/zksync/interfaces/IMailbox.sol"; +//import {TransactionValidator} from "solpp/zksync/libraries/TransactionValidator.sol"; +import {TransactionValidator} from "cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol"; + +contract TransactionValidatorSharedTest is Test { + constructor() {} + + function createTestTransaction() public pure returns (IMailbox.L2CanonicalTransaction memory testTx) { + testTx = IMailbox.L2CanonicalTransaction({ + txType: 0, + from: uint256(uint160(1_000_000_000)), + to: uint256(uint160(0)), + gasLimit: 500000, + gasPerPubdataByteLimit: 800, + maxFeePerGas: uint256(0), + maxPriorityFeePerGas: uint256(0), + paymaster: uint256(0), + nonce: uint256(0), + value: 0, + reserved: [uint256(0), uint256(0), uint256(0), uint256(0)], + data: new bytes(0), + signature: new bytes(0), + factoryDeps: new uint256[](0), + paymasterInput: new bytes(0), + reservedDynamic: new bytes(0) + }); + } + + function createUpgradeTransaction() public pure returns (IMailbox.L2CanonicalTransaction memory testTx) { + testTx = createTestTransaction(); + testTx.from = uint256(0x8001); + testTx.to = uint256(0x8007); + } + + function validateL1ToL2Transaction( + IMailbox.L2CanonicalTransaction memory _transaction, + uint256 _priorityTxMaxGasLimit + ) public pure { + TransactionValidator.validateL1ToL2Transaction(_transaction, abi.encode(_transaction), _priorityTxMaxGasLimit); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/UncheckedMath/UncheckedAdd.t.sol b/l1-contracts/test/foundry/unit/concrete/UncheckedMath/UncheckedAdd.t.sol new file mode 100644 index 000000000..847818a65 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/UncheckedMath/UncheckedAdd.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {UncheckedMathTest} from "./_UncheckedMath_Shared.t.sol"; +import {UncheckedMath} from "solpp/common/libraries/UncheckedMath.sol"; + +contract UncheckedAddTest is UncheckedMathTest { + using UncheckedMath for uint256; + + function test_Add() public { + uint256 a = 1234; + uint256 b = 4321; + uint256 c = a.uncheckedAdd(b); + assertEq(c, 5555); + } + + function test_AddWithOverflow() public { + uint256 a = type(uint256).max; + uint256 b = 1; + + // uncheckedAdd does not fail + uint256 c = a.uncheckedAdd(b); + assertEq(c, 0); + + // regular addition fails with overflow + vm.expectRevert(); + a + b; + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/UncheckedMath/UncheckedInc.t.sol b/l1-contracts/test/foundry/unit/concrete/UncheckedMath/UncheckedInc.t.sol new file mode 100644 index 000000000..aa1a669f7 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/UncheckedMath/UncheckedInc.t.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {UncheckedMathTest} from "./_UncheckedMath_Shared.t.sol"; +import {UncheckedMath} from "solpp/common/libraries/UncheckedMath.sol"; + +contract UncheckedIncTest is UncheckedMathTest { + using UncheckedMath for uint256; + + function test_Inc() public { + uint256 a = 1234; + uint256 c = a.uncheckedInc(); + assertEq(c, 1235); + } + + function test_IncWithOverflow() public { + uint256 a = type(uint256).max; + + // uncheckedInc does not fail + uint256 c = a.uncheckedInc(); + assertEq(c, 0); + + // regular addition fails with overflow + vm.expectRevert(); + a + 1; + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/UncheckedMath/_UncheckedMath_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/UncheckedMath/_UncheckedMath_Shared.t.sol new file mode 100644 index 000000000..badc0233e --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/UncheckedMath/_UncheckedMath_Shared.t.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {Test} from "forge-std/Test.sol"; + +contract UncheckedMathTest is Test {} diff --git a/ethereum/test/foundry/unit/concrete/UnsafeBytes/UnsafeBytes.t.sol b/l1-contracts/test/foundry/unit/concrete/UnsafeBytes/UnsafeBytes.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/UnsafeBytes/UnsafeBytes.t.sol rename to l1-contracts/test/foundry/unit/concrete/UnsafeBytes/UnsafeBytes.t.sol diff --git a/ethereum/test/foundry/unit/concrete/Utils/Utils.sol b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol similarity index 89% rename from ethereum/test/foundry/unit/concrete/Utils/Utils.sol rename to l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol index e462aaf5f..b97fdf183 100644 --- a/ethereum/test/foundry/unit/concrete/Utils/Utils.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol @@ -118,17 +118,16 @@ library Utils { selectors[15] = GettersFacet.getVerifierParams.selector; selectors[16] = GettersFacet.isDiamondStorageFrozen.selector; selectors[17] = GettersFacet.getPriorityTxMaxGasLimit.selector; - selectors[18] = GettersFacet.getAllowList.selector; - selectors[19] = GettersFacet.isEthWithdrawalFinalized.selector; - selectors[20] = GettersFacet.facets.selector; - selectors[21] = GettersFacet.facetFunctionSelectors.selector; - selectors[22] = GettersFacet.facetAddresses.selector; - selectors[23] = GettersFacet.facetAddress.selector; - selectors[24] = GettersFacet.isFunctionFreezable.selector; - selectors[25] = GettersFacet.isFacetFreezable.selector; - selectors[26] = GettersFacet.getTotalBatchesCommitted.selector; - selectors[27] = GettersFacet.getTotalBatchesVerified.selector; - selectors[28] = GettersFacet.getTotalBatchesExecuted.selector; + selectors[18] = GettersFacet.isEthWithdrawalFinalized.selector; + selectors[19] = GettersFacet.facets.selector; + selectors[20] = GettersFacet.facetFunctionSelectors.selector; + selectors[21] = GettersFacet.facetAddresses.selector; + selectors[22] = GettersFacet.facetAddress.selector; + selectors[23] = GettersFacet.isFunctionFreezable.selector; + selectors[24] = GettersFacet.isFacetFreezable.selector; + selectors[25] = GettersFacet.getTotalBatchesCommitted.selector; + selectors[26] = GettersFacet.getTotalBatchesVerified.selector; + selectors[27] = GettersFacet.getTotalBatchesExecuted.selector; return selectors; } diff --git a/ethereum/test/foundry/unit/concrete/Utils/Utils.t.sol b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.t.sol similarity index 100% rename from ethereum/test/foundry/unit/concrete/Utils/Utils.t.sol rename to l1-contracts/test/foundry/unit/concrete/Utils/Utils.t.sol diff --git a/l1-contracts/test/foundry/unit/concrete/Verifier/Verifier.t.sol b/l1-contracts/test/foundry/unit/concrete/Verifier/Verifier.t.sol new file mode 100644 index 000000000..94dd208a7 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/Verifier/Verifier.t.sol @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {Test} from "forge-std/Test.sol"; +import {VerifierTest} from "solpp/dev-contracts/test/VerifierTest.sol"; +import {Verifier} from "solpp/zksync/Verifier.sol"; + +contract VerifierTestTest is Test { + uint256 Q_MOD = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + uint256 R_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + + uint256[] public publicInputs; + uint256[] public serializedProof; + uint256[] public recursiveAggregationInput; + + Verifier public verifier; + + function setUp() public virtual { + publicInputs.push(17257057577815541751225964212897374444694342989384539141520877492729); + + serializedProof.push(10032255692304426541958487424837706541667730769782503366592797609781788557424); + serializedProof.push(11856023086316274558845067687080284266010851703055534566998849536424959073766); + serializedProof.push(1946976494418613232642071265529572704802622739887191787991738703483400525159); + serializedProof.push(1328106069458824013351862477593422369726189688844441245167676630500797673929); + serializedProof.push(15488976127650523079605218040232167291115155239002840072043251018873550258833); + serializedProof.push(4352460820258659596860226525221943504756149602617718032378962471842121872064); + serializedProof.push(10499239305859992443759785453270906003243074359959242371675950941500942473773); + serializedProof.push(21347231097799123231227724221565041889687686131480556177475242020711996173235); + serializedProof.push(21448274562455512652922184359722637546669181231038098300951155169465175447933); + serializedProof.push(5224615512030263722410009061780530125927659699046094954022444377569738464640); + serializedProof.push(457781538876079938778845275495204146302569607395268192839148474821758081582); + serializedProof.push(18861735728246155975127314860333796285284072325207684293054713266899263027595); + serializedProof.push(16303944945368742900183889655415585360236645961122617249176044814801835577336); + serializedProof.push(13035945439947210396602249585896632733250124877036427100939804737514358838409); + serializedProof.push(5344210729159253547334947774998425118220137275601995670629358314205854915831); + serializedProof.push(5798533246034358556434877465898581616792677631188370022078168611592512620805); + serializedProof.push(17389657286129893116489015409587246992530648956814855147744210777822507444908); + serializedProof.push(2287244647342394712608648573347732257083870498255199596324312699868511383792); + serializedProof.push(4008043766112513713076111464601725311991199944328610186851424132679188418647); + serializedProof.push(1192776719848445147414966176395169615865534126881763324071908049917030138759); + serializedProof.push(21297794452895123333253856666749932934399762330444876027734824957603009458926); + serializedProof.push(17125994169200693606182326100834606153690416627082476471630567824088261322122); + serializedProof.push(13696978282153979214307382954559709118587582183649354744253374201589715565327); + serializedProof.push(19885518441500677676836488338931187143852666523909650686513498826535451677070); + serializedProof.push(1205434280320863211046275554464591162919269140938371417889032165323835178587); + serializedProof.push(17633172995805911347980792921300006225132501482343225088847242025756974009163); + serializedProof.push(16438080406761371143473961144300947125022788905488819913014533292593141026205); + serializedProof.push(5069081552536259237104332491140391551180511112980430307676595350165020188468); + serializedProof.push(21217317205917200275887696442048162383709998732382676029165079037795626916156); + serializedProof.push(19474466610515117278975027596198570980840609656738255347763182823792179771539); + serializedProof.push(9744176601826774967534277982058590459006781888895542911226406188087317156914); + serializedProof.push(13171230402193025939763214267878900142876558410430734782028402821166810894141); + serializedProof.push(11775403006142607980192261369108550982244126464568678337528680604943636677964); + serializedProof.push(6903612341636669639883555213872265187697278660090786759295896380793937349335); + serializedProof.push(10197105415769290664169006387603164525075746474380469980600306405504981186043); + serializedProof.push(10143152486514437388737642096964118742712576889537781270260677795662183637771); + serializedProof.push(7662095231333811948165764727904932118187491073896301295018543320499906824310); + serializedProof.push(929422796511992741418500336817719055655694499787310043166783539202506987065); + serializedProof.push(13837024938095280064325737989251964639823205065380219552242839155123572433059); + serializedProof.push(11738888513780631372636453609299803548810759208935038785934252961078387526204); + serializedProof.push(16528875312985292109940444015943812939751717229020635856725059316776921546668); + serializedProof.push(17525167117689648878398809303253004706004801107861280044640132822626802938868); + serializedProof.push(7419167499813234488108910149511390953153207250610705609008080038658070088540); + serializedProof.push(11628425014048216611195735618191126626331446742771562481735017471681943914146); + + verifier = new VerifierTest(); + } + + function testShouldVerify() public view { + bool success = verifier.verify(publicInputs, serializedProof, recursiveAggregationInput); + assert(success); + } + + function testShouldVerifyWithDirtyBits() public view { + uint256[] memory newPublicInputs = publicInputs; + newPublicInputs[0] += uint256(bytes32(0xe000000000000000000000000000000000000000000000000000000000000000)); + + bool success = verifier.verify(newPublicInputs, serializedProof, recursiveAggregationInput); + assert(success); + } + + function testEllipticCurvePointsOverModulo() public view { + uint256[] memory newSerializedProof = serializedProof; + newSerializedProof[0] += Q_MOD; + newSerializedProof[1] += Q_MOD; + newSerializedProof[1] += Q_MOD; + + bool success = verifier.verify(publicInputs, newSerializedProof, recursiveAggregationInput); + assert(success); + } + + function testFrOverModulo() public view { + uint256[] memory newSerializedProof = serializedProof; + newSerializedProof[22] += R_MOD; + + bool success = verifier.verify(publicInputs, newSerializedProof, recursiveAggregationInput); + assert(success); + } + + function testMoreThanOnePublicInput_shouldRevert() public { + uint256[] memory newPublicInputs = new uint256[](2); + newPublicInputs[0] = publicInputs[0]; + newPublicInputs[1] = publicInputs[0]; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(newPublicInputs, serializedProof, recursiveAggregationInput); + } + + function testEmptyPublicInput_shouldRevert() public { + uint256[] memory newPublicInputs; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(newPublicInputs, serializedProof, recursiveAggregationInput); + } + + function testMoreThan44WordsProof_shouldRevert() public { + uint256[] memory newSerializedProof = new uint256[](serializedProof.length + 1); + + for (uint256 i = 0; i < serializedProof.length; i++) { + newSerializedProof[i] = serializedProof[i]; + } + newSerializedProof[newSerializedProof.length - 1] = serializedProof[serializedProof.length - 1]; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(publicInputs, newSerializedProof, recursiveAggregationInput); + } + + function testEmptyProof_shouldRevert() public { + uint256[] memory newSerializedProof; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(publicInputs, newSerializedProof, recursiveAggregationInput); + } + + function testNotEmptyRecursiveAggregationInput_shouldRevert() public { + uint256[] memory newRecursiveAggregationInput = publicInputs; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(publicInputs, serializedProof, newRecursiveAggregationInput); + } + + function testEllipticCurvePointAtInfinity_shouldRevert() public { + uint256[] memory newSerializedProof = serializedProof; + newSerializedProof[0] = 0; + newSerializedProof[1] = 0; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(publicInputs, newSerializedProof, recursiveAggregationInput); + } + + function testInvalidPublicInput_shouldRevert() public { + uint256[] memory newPublicInputs = publicInputs; + newPublicInputs[0] = 0; + + vm.expectRevert(bytes("invalid quotient evaluation")); + verifier.verify(newPublicInputs, serializedProof, recursiveAggregationInput); + } + + function testVerificationKeyHash() public virtual { + bytes32 verificationKeyHash = verifier.verificationKeyHash(); + assertEq(verificationKeyHash, 0x6625fa96781746787b58306d414b1e25bd706d37d883a9b3acf57b2bd5e0de52); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/Verifier/VerifierRecursive.t.sol b/l1-contracts/test/foundry/unit/concrete/Verifier/VerifierRecursive.t.sol new file mode 100644 index 000000000..480bf2c73 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/Verifier/VerifierRecursive.t.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {VerifierTestTest} from "./Verifier.t.sol"; +import {VerifierRecursiveTest} from "solpp/dev-contracts/test/VerifierRecursiveTest.sol"; + +contract VerifierRecursiveTestTest is VerifierTestTest { + function setUp() public override { + super.setUp(); + + recursiveAggregationInput.push(2257920826825449939414463854743099397427742128922725774525544832270890253504); + recursiveAggregationInput.push(9091218701914748532331969127001446391756173432977615061129552313204917562530); + recursiveAggregationInput.push(16188304989094043810949359833767911976672882599560690320245309499206765021563); + recursiveAggregationInput.push(3201093556796962656759050531176732990872300033146738631772984017549903765305); + + verifier = new VerifierRecursiveTest(); + } + + function testMoreThan4WordsRecursiveInput_shouldRevert() public { + uint256[] memory newRecursiveAggregationInput = new uint256[](recursiveAggregationInput.length + 1); + + for (uint256 i = 0; i < recursiveAggregationInput.length; i++) { + newRecursiveAggregationInput[i] = recursiveAggregationInput[i]; + } + newRecursiveAggregationInput[newRecursiveAggregationInput.length - 1] = recursiveAggregationInput[ + recursiveAggregationInput.length - 1 + ]; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(publicInputs, serializedProof, newRecursiveAggregationInput); + } + + function testEmptyRecursiveInput_shouldRevert() public { + uint256[] memory newRecursiveAggregationInput; + + vm.expectRevert(bytes("loadProof: Proof is invalid")); + verifier.verify(publicInputs, serializedProof, newRecursiveAggregationInput); + } + + function testInvalidRecursiveInput_shouldRevert() public { + uint256[] memory newRecursiveAggregationInput = new uint256[](4); + newRecursiveAggregationInput[0] = 1; + newRecursiveAggregationInput[1] = 2; + newRecursiveAggregationInput[2] = 1; + newRecursiveAggregationInput[3] = 2; + + vm.expectRevert(bytes("finalPairing: pairing failure")); + verifier.verify(publicInputs, serializedProof, newRecursiveAggregationInput); + } + + function testVerificationKeyHash() public override { + bytes32 verificationKeyHash = verifier.verificationKeyHash(); + assertEq(verificationKeyHash, 0x88b3ddc4ed85974c7e14297dcad4097169440305c05fdb6441ca8dfd77cd7fa7); + } +} diff --git a/ethereum/test/unit_tests/erc20-bridge-upgrade.fork.ts b/l1-contracts/test/unit_tests/erc20-bridge-upgrade.fork.ts similarity index 88% rename from ethereum/test/unit_tests/erc20-bridge-upgrade.fork.ts rename to l1-contracts/test/unit_tests/erc20-bridge-upgrade.fork.ts index fbd2997ff..4559f835a 100644 --- a/ethereum/test/unit_tests/erc20-bridge-upgrade.fork.ts +++ b/l1-contracts/test/unit_tests/erc20-bridge-upgrade.fork.ts @@ -24,7 +24,6 @@ async function isPromiseFailed(promise: Promise): Promise { } describe("L1 ERC20 proxy upgrade fork test", function () { - const allowListOnNewImplementation = "0xdeadbeafdeadbeafdeadbeafdeadbeafdeadbeaf"; const mailboxOnNewImplementation = "0x1234567890123456789012345678901234567890"; let governor: ethers.Signer; @@ -44,16 +43,13 @@ describe("L1 ERC20 proxy upgrade fork test", function () { oldBridgeImplementationAddress = await bridgeProxy.connect(governor).callStatic.implementation(); const l1Erc20BridgeFactory = await hardhat.ethers.getContractFactory("L1ERC20BridgeTest"); - const l1Erc20Bridge = await l1Erc20BridgeFactory.deploy(mailboxOnNewImplementation, allowListOnNewImplementation); + const l1Erc20Bridge = await l1Erc20BridgeFactory.deploy(mailboxOnNewImplementation); newBridgeImplementation = L1ERC20BridgeTestFactory.connect(l1Erc20Bridge.address, l1Erc20Bridge.signer); }); it("should revert on non-existed methods", async () => { const bridgeProxyAsNewImplementation = L1ERC20BridgeTestFactory.connect(bridgeProxy.address, randomSigner); - const failedGetAllowList = await isPromiseFailed(bridgeProxyAsNewImplementation.getAllowList()); - expect(failedGetAllowList).to.be.true; - const failedGetMailbox = await isPromiseFailed(bridgeProxyAsNewImplementation.getZkSyncMailbox()); expect(failedGetMailbox).to.be.true; }); @@ -65,9 +61,6 @@ describe("L1 ERC20 proxy upgrade fork test", function () { it("check new functions", async () => { const bridgeProxyAsNewImplementation = L1ERC20BridgeTestFactory.connect(bridgeProxy.address, randomSigner); - const allowlist = await bridgeProxyAsNewImplementation.getAllowList(); - expect(allowlist.toLocaleLowerCase()).to.be.eq(allowListOnNewImplementation.toLocaleLowerCase()); - const mailbox = await bridgeProxyAsNewImplementation.getZkSyncMailbox(); expect(mailbox.toLocaleLowerCase()).to.be.eq(mailboxOnNewImplementation.toLocaleLowerCase()); }); diff --git a/ethereum/test/unit_tests/executor_proof.spec.ts b/l1-contracts/test/unit_tests/executor_proof.spec.ts similarity index 100% rename from ethereum/test/unit_tests/executor_proof.spec.ts rename to l1-contracts/test/unit_tests/executor_proof.spec.ts diff --git a/ethereum/test/unit_tests/governance_test.spec.ts b/l1-contracts/test/unit_tests/governance_test.spec.ts similarity index 100% rename from ethereum/test/unit_tests/governance_test.spec.ts rename to l1-contracts/test/unit_tests/governance_test.spec.ts diff --git a/ethereum/test/unit_tests/l1_erc20_bridge_test.spec.ts b/l1-contracts/test/unit_tests/l1_erc20_bridge_test.spec.ts similarity index 87% rename from ethereum/test/unit_tests/l1_erc20_bridge_test.spec.ts rename to l1-contracts/test/unit_tests/l1_erc20_bridge_test.spec.ts index fb74c52d4..a28a85d7d 100644 --- a/ethereum/test/unit_tests/l1_erc20_bridge_test.spec.ts +++ b/l1-contracts/test/unit_tests/l1_erc20_bridge_test.spec.ts @@ -5,9 +5,8 @@ import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-web3/build/src/u import type { IZkSync } from "zksync-web3/build/typechain"; import { IZkSyncFactory } from "zksync-web3/build/typechain"; import { Action, diamondCut, facetCut } from "../../src.ts/diamondCut"; -import type { AllowList, TestnetERC20Token } from "../../typechain"; +import type { TestnetERC20Token } from "../../typechain"; import { - AllowListFactory, DiamondInitFactory, GettersFacetFactory, MailboxFacetFactory, @@ -15,12 +14,11 @@ import { } from "../../typechain"; import type { IL1Bridge } from "../../typechain/IL1Bridge"; import { IL1BridgeFactory } from "../../typechain/IL1BridgeFactory"; -import { AccessMode, getCallRevertReason } from "./utils"; +import { getCallRevertReason } from "./utils"; describe("L1ERC20Bridge tests", function () { let owner: ethers.Signer; let randomSigner: ethers.Signer; - let allowList: AllowList; let l1ERC20Bridge: IL1Bridge; let erc20TestToken: TestnetERC20Token; let testnetERC20TokenContract: ethers.Contract; @@ -38,10 +36,6 @@ describe("L1ERC20Bridge tests", function () { const mailboxContract = await mailboxFactory.deploy(); const mailboxFacet = MailboxFacetFactory.connect(mailboxContract.address, mailboxContract.signer); - const allowListFactory = await hardhat.ethers.getContractFactory("AllowList"); - const allowListContract = await allowListFactory.deploy(await allowListFactory.signer.getAddress()); - allowList = AllowListFactory.connect(allowListContract.address, allowListContract.signer); - const diamondInitFactory = await hardhat.ethers.getContractFactory("DiamondInit"); const diamondInitContract = await diamondInitFactory.deploy(); const diamondInit = DiamondInitFactory.connect(diamondInitContract.address, diamondInitContract.signer); @@ -57,7 +51,6 @@ describe("L1ERC20Bridge tests", function () { genesisBatchHash: ethers.constants.HashZero, genesisIndexRepeatedStorageChanges: 0, genesisBatchCommitment: ethers.constants.HashZero, - allowList: allowList.address, verifierParams: { recursionCircuitsSetVksHash: ethers.constants.HashZero, recursionLeafLevelVkHash: ethers.constants.HashZero, @@ -83,7 +76,7 @@ describe("L1ERC20Bridge tests", function () { const diamondProxyContract = await diamondProxyFactory.deploy(chainId, diamondCutData); const l1Erc20BridgeFactory = await hardhat.ethers.getContractFactory("L1ERC20Bridge"); - l1Erc20BridgeContract = await l1Erc20BridgeFactory.deploy(diamondProxyContract.address, allowListContract.address); + l1Erc20BridgeContract = await l1Erc20BridgeFactory.deploy(diamondProxyContract.address); l1ERC20Bridge = IL1BridgeFactory.connect(l1Erc20BridgeContract.address, l1Erc20BridgeContract.signer); const testnetERC20TokenFactory = await hardhat.ethers.getContractFactory("TestnetERC20Token"); @@ -98,30 +91,10 @@ describe("L1ERC20Bridge tests", function () { .connect(randomSigner) .approve(l1Erc20BridgeContract.address, ethers.utils.parseUnits("10000", 18)); - await (await allowList.setAccessMode(diamondProxyContract.address, AccessMode.Public)).wait(); - // Exposing the methods of IZkSync to the diamond proxy zksyncContract = IZkSyncFactory.connect(diamondProxyContract.address, diamondProxyContract.provider); }); - it("Should not allow an un-whitelisted address to deposit", async () => { - const revertReason = await getCallRevertReason( - l1ERC20Bridge - .connect(randomSigner) - .deposit( - await randomSigner.getAddress(), - testnetERC20TokenContract.address, - 0, - 0, - 0, - ethers.constants.AddressZero - ) - ); - expect(revertReason).equal("nr"); - - await (await allowList.setAccessMode(l1Erc20BridgeContract.address, AccessMode.Public)).wait(); - }); - it("Should not allow depositing zero amount", async () => { const revertReason = await getCallRevertReason( l1ERC20Bridge diff --git a/ethereum/test/unit_tests/l1_weth_bridge_test.spec.ts b/l1-contracts/test/unit_tests/l1_weth_bridge_test.spec.ts similarity index 86% rename from ethereum/test/unit_tests/l1_weth_bridge_test.spec.ts rename to l1-contracts/test/unit_tests/l1_weth_bridge_test.spec.ts index 6fe7f1fa1..21bd29fa0 100644 --- a/ethereum/test/unit_tests/l1_weth_bridge_test.spec.ts +++ b/l1-contracts/test/unit_tests/l1_weth_bridge_test.spec.ts @@ -3,9 +3,8 @@ import { ethers } from "ethers"; import * as hardhat from "hardhat"; import { hashL2Bytecode } from "../../scripts/utils"; import { Action, diamondCut, facetCut } from "../../src.ts/diamondCut"; -import type { AllowList, L1WethBridge, WETH9 } from "../../typechain"; +import type { L1WethBridge, WETH9 } from "../../typechain"; import { - AllowListFactory, DiamondInitFactory, GettersFacetFactory, L1WethBridgeFactory, @@ -13,7 +12,7 @@ import { WETH9Factory, } from "../../typechain"; import type { IZkSync } from "../../typechain/IZkSync"; -import { AccessMode, getCallRevertReason } from "./utils"; +import { getCallRevertReason } from "./utils"; import { Interface } from "ethers/lib/utils"; import type { Address } from "zksync-web3/build/src/types"; @@ -52,7 +51,6 @@ export async function create2DeployFromL1( describe("WETH Bridge tests", () => { let owner: ethers.Signer; let randomSigner: ethers.Signer; - let allowList: AllowList; let bridgeProxy: L1WethBridge; let l1Weth: WETH9; const functionSignature = "0x6c0960f9"; @@ -70,10 +68,6 @@ describe("WETH Bridge tests", () => { const mailboxContract = await mailboxFactory.deploy(); const mailboxFacet = MailboxFacetFactory.connect(mailboxContract.address, mailboxContract.signer); - const allowListFactory = await hardhat.ethers.getContractFactory("AllowList"); - const allowListContract = await allowListFactory.deploy(await allowListFactory.signer.getAddress()); - allowList = AllowListFactory.connect(allowListContract.address, allowListContract.signer); - const diamondInitFactory = await hardhat.ethers.getContractFactory("DiamondInit"); const diamondInitContract = await diamondInitFactory.deploy(); const diamondInit = DiamondInitFactory.connect(diamondInitContract.address, diamondInitContract.signer); @@ -89,7 +83,6 @@ describe("WETH Bridge tests", () => { genesisBatchHash: ethers.constants.HashZero, genesisIndexRepeatedStorageChanges: 0, genesisBatchCommitment: ethers.constants.HashZero, - allowList: allowList.address, verifierParams: { recursionCircuitsSetVksHash: ethers.constants.HashZero, recursionLeafLevelVkHash: ethers.constants.HashZero, @@ -114,15 +107,13 @@ describe("WETH Bridge tests", () => { const chainId = hardhat.network.config.chainId; const diamondProxyContract = await diamondProxyFactory.deploy(chainId, diamondCutData); - await (await allowList.setAccessMode(diamondProxyContract.address, AccessMode.Public)).wait(); - l1Weth = WETH9Factory.connect((await (await hardhat.ethers.getContractFactory("WETH9")).deploy()).address, owner); // prepare the bridge const bridge = await ( await hardhat.ethers.getContractFactory("L1WethBridge") - ).deploy(l1Weth.address, diamondProxyContract.address, allowListContract.address); + ).deploy(l1Weth.address, diamondProxyContract.address); // we don't test L2, so it is ok to give garbage factory deps and L2 address const garbageBytecode = "0x1111111111111111111111111111111111111111111111111111111111111111"; @@ -142,19 +133,6 @@ describe("WETH Bridge tests", () => { bridgeProxy = L1WethBridgeFactory.connect(_bridgeProxy.address, _bridgeProxy.signer); }); - it("Should not allow an un-whitelisted address to deposit", async () => { - const revertReason = await getCallRevertReason( - bridgeProxy - .connect(randomSigner) - .deposit(await randomSigner.getAddress(), ethers.constants.AddressZero, 0, 0, 0, ethers.constants.AddressZero) - ); - - expect(revertReason).equal("nr"); - - // This is only so the following tests don't need whitelisting - await (await allowList.setAccessMode(bridgeProxy.address, AccessMode.Public)).wait(); - }); - it("Should not allow depositing zero WETH", async () => { const revertReason = await getCallRevertReason( bridgeProxy diff --git a/ethereum/test/unit_tests/l2-upgrade.test.spec.ts b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts similarity index 98% rename from ethereum/test/unit_tests/l2-upgrade.test.spec.ts rename to l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts index 49341c9bf..f5e75e76b 100644 --- a/ethereum/test/unit_tests/l2-upgrade.test.spec.ts +++ b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts @@ -1,10 +1,9 @@ import { expect } from "chai"; import * as hardhat from "hardhat"; import { Action, facetCut, diamondCut } from "../../src.ts/diamondCut"; -import type { AllowList, ExecutorFacet, GettersFacet, AdminFacet } from "../../typechain"; +import type { ExecutorFacet, GettersFacet, AdminFacet } from "../../typechain"; import { DiamondInitFactory, - AllowListFactory, ExecutorFacetFactory, GettersFacetFactory, AdminFacetFactory, @@ -14,7 +13,6 @@ import { import type { StoredBatchInfo, CommitBatchInfo } from "./utils"; import { getCallRevertReason, - AccessMode, EMPTY_STRING_KECCAK, genesisStoredBatchInfo, L2_SYSTEM_CONTEXT_ADDRESS, @@ -35,7 +33,6 @@ describe("L2 upgrade test", function () { let proxyAdmin: AdminFacet; let proxyGetters: GettersFacet; - let allowList: AllowList; let diamondProxyContract: ethers.Contract; let owner: ethers.Signer; @@ -61,10 +58,6 @@ describe("L2 upgrade test", function () { const adminFacetContract = await adminFacetFactory.deploy(); const adminFacet = AdminFacetFactory.connect(adminFacetContract.address, adminFacetContract.signer); - const allowListFactory = await hardhat.ethers.getContractFactory("AllowList"); - const allowListContract = await allowListFactory.deploy(await allowListFactory.signer.getAddress()); - allowList = AllowListFactory.connect(allowListContract.address, allowListContract.signer); - // Note, that while this testsuit is focused on testing MailboxFaucet only, // we still need to initialize its storage via DiamondProxy const diamondInitFactory = await hardhat.ethers.getContractFactory("DiamondInit"); @@ -87,7 +80,6 @@ describe("L2 upgrade test", function () { genesisBatchHash: ethers.constants.HashZero, genesisIndexRepeatedStorageChanges: 0, genesisBatchCommitment: ethers.constants.HashZero, - allowList: allowList.address, verifierParams, zkPorterIsAvailable: false, l2BootloaderBytecodeHash: dummyHash, @@ -112,8 +104,6 @@ describe("L2 upgrade test", function () { const chainId = hardhat.network.config.chainId; diamondProxyContract = await diamondProxyFactory.deploy(chainId, diamondCutData); - await (await allowList.setAccessMode(diamondProxyContract.address, AccessMode.Public)).wait(); - proxyExecutor = ExecutorFacetFactory.connect(diamondProxyContract.address, owner); proxyGetters = GettersFacetFactory.connect(diamondProxyContract.address, owner); proxyAdmin = AdminFacetFactory.connect(diamondProxyContract.address, owner); diff --git a/ethereum/test/unit_tests/mailbox_test.spec.ts b/l1-contracts/test/unit_tests/mailbox_test.spec.ts similarity index 70% rename from ethereum/test/unit_tests/mailbox_test.spec.ts rename to l1-contracts/test/unit_tests/mailbox_test.spec.ts index a1a704f59..84564f5e4 100644 --- a/ethereum/test/unit_tests/mailbox_test.spec.ts +++ b/l1-contracts/test/unit_tests/mailbox_test.spec.ts @@ -1,36 +1,22 @@ import { expect } from "chai"; import * as hardhat from "hardhat"; import { Action, facetCut, diamondCut } from "../../src.ts/diamondCut"; -import type { MailboxFacet, MockExecutorFacet, AllowList, Forwarder } from "../../typechain"; -import { - MailboxFacetFactory, - MockExecutorFacetFactory, - DiamondInitFactory, - AllowListFactory, - ForwarderFactory, -} from "../../typechain"; -import { - DEFAULT_REVERT_REASON, - getCallRevertReason, - AccessMode, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - requestExecute, -} from "./utils"; +import type { MailboxFacet, MockExecutorFacet, Forwarder } from "../../typechain"; +import { MailboxFacetFactory, MockExecutorFacetFactory, DiamondInitFactory, ForwarderFactory } from "../../typechain"; +import { DEFAULT_REVERT_REASON, getCallRevertReason, REQUIRED_L2_GAS_PRICE_PER_PUBDATA, requestExecute } from "./utils"; import * as ethers from "ethers"; describe("Mailbox tests", function () { let mailbox: MailboxFacet; let proxyAsMockExecutor: MockExecutorFacet; - let allowList: AllowList; let diamondProxyContract: ethers.Contract; let owner: ethers.Signer; - let randomSigner: ethers.Signer; const MAX_CODE_LEN_WORDS = (1 << 16) - 1; const MAX_CODE_LEN_BYTES = MAX_CODE_LEN_WORDS * 32; let forwarder: Forwarder; before(async () => { - [owner, randomSigner] = await hardhat.ethers.getSigners(); + [owner] = await hardhat.ethers.getSigners(); const mailboxFactory = await hardhat.ethers.getContractFactory("MailboxFacet"); const mailboxContract = await mailboxFactory.deploy(); @@ -43,10 +29,6 @@ describe("Mailbox tests", function () { mockExecutorContract.signer ); - const allowListFactory = await hardhat.ethers.getContractFactory("AllowList"); - const allowListContract = await allowListFactory.deploy(await allowListFactory.signer.getAddress()); - allowList = AllowListFactory.connect(allowListContract.address, allowListContract.signer); - // Note, that while this testsuit is focused on testing MailboxFaucet only, // we still need to initialize its storage via DiamondProxy const diamondInitFactory = await hardhat.ethers.getContractFactory("DiamondInit"); @@ -64,7 +46,6 @@ describe("Mailbox tests", function () { genesisBatchHash: ethers.constants.HashZero, genesisIndexRepeatedStorageChanges: 0, genesisBatchCommitment: ethers.constants.HashZero, - allowList: allowList.address, verifierParams: { recursionCircuitsSetVksHash: ethers.constants.HashZero, recursionLeafLevelVkHash: ethers.constants.HashZero, @@ -88,8 +69,6 @@ describe("Mailbox tests", function () { const chainId = hardhat.network.config.chainId; diamondProxyContract = await diamondProxyFactory.deploy(chainId, diamondCutData); - await (await allowList.setAccessMode(diamondProxyContract.address, AccessMode.Public)).wait(); - mailbox = MailboxFacetFactory.connect(diamondProxyContract.address, mailboxContract.signer); proxyAsMockExecutor = MockExecutorFacetFactory.connect(diamondProxyContract.address, mockExecutorContract.signer); @@ -165,67 +144,6 @@ describe("Mailbox tests", function () { expect(revertReason).equal("pp"); }); - describe("Deposit and Withdrawal limit functionality", function () { - const DEPOSIT_LIMIT = ethers.utils.parseEther("10"); - - before(async () => { - await allowList.setDepositLimit(ethers.constants.AddressZero, true, DEPOSIT_LIMIT); - }); - - it("Should not accept depositing more than the deposit limit", async () => { - const revertReason = await getCallRevertReason( - requestExecute( - mailbox, - ethers.constants.AddressZero, - ethers.utils.parseEther("12"), - "0x", - ethers.BigNumber.from(100000), - [new Uint8Array(32)], - ethers.constants.AddressZero - ) - ); - - expect(revertReason).equal("d2"); - }); - - it("Should accept depositing less than or equal to the deposit limit", async () => { - const gasPrice = await mailbox.provider.getGasPrice(); - const l2GasLimit = ethers.BigNumber.from(1000000); - const l2Cost = await mailbox.l2TransactionBaseCost(gasPrice, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); - - const revertReason = await getCallRevertReason( - requestExecute( - mailbox, - ethers.constants.AddressZero, - DEPOSIT_LIMIT.sub(l2Cost), - "0x", - l2GasLimit, - [new Uint8Array(32)], - ethers.constants.AddressZero, - { gasPrice } - ) - ); - - expect(revertReason).equal(DEFAULT_REVERT_REASON); - }); - - it("Should not accept depositing that the accumulation is more than the deposit limit", async () => { - const revertReason = await getCallRevertReason( - requestExecute( - mailbox, - ethers.constants.AddressZero, - ethers.BigNumber.from(1), - "0x", - ethers.BigNumber.from(1000000), - [new Uint8Array(32)], - ethers.constants.AddressZero - ) - ); - - expect(revertReason).equal("d2"); - }); - }); - describe("finalizeEthWithdrawal", function () { const BLOCK_NUMBER = 1; const MESSAGE_INDEX = 0; @@ -280,48 +198,6 @@ describe("Mailbox tests", function () { }); }); - describe("Access mode functionality", function () { - before(async () => { - // We still need to set infinite amount of allowed deposit limit in order to ensure that every fee will be accepted - await allowList.setDepositLimit(ethers.constants.AddressZero, true, ethers.utils.parseEther("2000")); - }); - - it("Should not allow an un-whitelisted address to call", async () => { - await allowList.setAccessMode(diamondProxyContract.address, AccessMode.Closed); - - const revertReason = await getCallRevertReason( - requestExecute( - mailbox.connect(randomSigner), - ethers.constants.AddressZero, - ethers.BigNumber.from(0), - "0x", - ethers.BigNumber.from(100000), - [new Uint8Array(32)], - ethers.constants.AddressZero - ) - ); - expect(revertReason).equal("nr"); - }); - - it("Should allow the whitelisted address to call", async () => { - await allowList.setAccessMode(diamondProxyContract.address, AccessMode.SpecialAccessOnly); - await allowList.setPermissionToCall(await owner.getAddress(), diamondProxyContract.address, "0xeb672419", true); - - const revertReason = await getCallRevertReason( - requestExecute( - mailbox.connect(owner), - ethers.constants.AddressZero, - ethers.BigNumber.from(0), - "0x", - ethers.BigNumber.from(1000000), - [new Uint8Array(32)], - ethers.constants.AddressZero - ) - ); - expect(revertReason).equal(DEFAULT_REVERT_REASON); - }); - }); - let callDirectly, callViaForwarder, callViaConstructorForwarder; before(async () => { diff --git a/ethereum/test/unit_tests/proxy_test.spec.ts b/l1-contracts/test/unit_tests/proxy_test.spec.ts similarity index 99% rename from ethereum/test/unit_tests/proxy_test.spec.ts rename to l1-contracts/test/unit_tests/proxy_test.spec.ts index 076cd7fc9..d9e496f5a 100644 --- a/ethereum/test/unit_tests/proxy_test.spec.ts +++ b/l1-contracts/test/unit_tests/proxy_test.spec.ts @@ -77,7 +77,6 @@ describe("Diamond proxy tests", function () { genesisBatchHash: "0x02c775f0a90abf7a0e8043f2fdc38f0580ca9f9996a895d05a501bfeaa3b2e21", genesisIndexRepeatedStorageChanges: 0, genesisBatchCommitment: ethers.constants.HashZero, - allowList: "0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55", verifierParams: dummyVerifierParams, zkPorterIsAvailable: false, l2BootloaderBytecodeHash: "0x0100000000000000000000000000000000000000000000000000000000000000", diff --git a/ethereum/test/unit_tests/utils.ts b/l1-contracts/test/unit_tests/utils.ts similarity index 98% rename from ethereum/test/unit_tests/utils.ts rename to l1-contracts/test/unit_tests/utils.ts index 992de3792..1893134fb 100644 --- a/ethereum/test/unit_tests/utils.ts +++ b/l1-contracts/test/unit_tests/utils.ts @@ -39,12 +39,6 @@ export class DummyOp { ) {} } -export enum AccessMode { - Closed = 0, - SpecialAccessOnly = 1, - Public = 2, -} - export async function getCallRevertReason(promise) { let revertReason = DEFAULT_REVERT_REASON; try { diff --git a/ethereum/test/unit_tests/validator_timelock_test.spec.ts b/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts similarity index 100% rename from ethereum/test/unit_tests/validator_timelock_test.spec.ts rename to l1-contracts/test/unit_tests/validator_timelock_test.spec.ts diff --git a/ethereum/test/unit_tests/zksync-upgrade.fork.ts b/l1-contracts/test/unit_tests/zksync-upgrade.fork.ts similarity index 100% rename from ethereum/test/unit_tests/zksync-upgrade.fork.ts rename to l1-contracts/test/unit_tests/zksync-upgrade.fork.ts diff --git a/ethereum/tsconfig.json b/l1-contracts/tsconfig.json similarity index 100% rename from ethereum/tsconfig.json rename to l1-contracts/tsconfig.json diff --git a/ethereum/upgrade-system/facets.ts b/l1-contracts/upgrade-system/facets.ts similarity index 100% rename from ethereum/upgrade-system/facets.ts rename to l1-contracts/upgrade-system/facets.ts diff --git a/ethereum/upgrade-system/index.ts b/l1-contracts/upgrade-system/index.ts similarity index 100% rename from ethereum/upgrade-system/index.ts rename to l1-contracts/upgrade-system/index.ts diff --git a/ethereum/upgrade-system/utils.ts b/l1-contracts/upgrade-system/utils.ts similarity index 100% rename from ethereum/upgrade-system/utils.ts rename to l1-contracts/upgrade-system/utils.ts diff --git a/ethereum/upgrade-system/verifier.ts b/l1-contracts/upgrade-system/verifier.ts similarity index 100% rename from ethereum/upgrade-system/verifier.ts rename to l1-contracts/upgrade-system/verifier.ts diff --git a/zksync/.env b/l2-contracts/.env similarity index 100% rename from zksync/.env rename to l2-contracts/.env diff --git a/zksync/contracts/Dependencies.sol b/l2-contracts/contracts/Dependencies.sol similarity index 100% rename from zksync/contracts/Dependencies.sol rename to l2-contracts/contracts/Dependencies.sol diff --git a/zksync/contracts/ForceDeployUpgrader.sol b/l2-contracts/contracts/ForceDeployUpgrader.sol similarity index 100% rename from zksync/contracts/ForceDeployUpgrader.sol rename to l2-contracts/contracts/ForceDeployUpgrader.sol diff --git a/zksync/contracts/L2ContractHelper.sol b/l2-contracts/contracts/L2ContractHelper.sol similarity index 100% rename from zksync/contracts/L2ContractHelper.sol rename to l2-contracts/contracts/L2ContractHelper.sol diff --git a/zksync/contracts/SystemContractsCaller.sol b/l2-contracts/contracts/SystemContractsCaller.sol similarity index 100% rename from zksync/contracts/SystemContractsCaller.sol rename to l2-contracts/contracts/SystemContractsCaller.sol diff --git a/zksync/contracts/TestnetPaymaster.sol b/l2-contracts/contracts/TestnetPaymaster.sol similarity index 100% rename from zksync/contracts/TestnetPaymaster.sol rename to l2-contracts/contracts/TestnetPaymaster.sol diff --git a/zksync/contracts/bridge/L2ERC20Bridge.sol b/l2-contracts/contracts/bridge/L2ERC20Bridge.sol similarity index 100% rename from zksync/contracts/bridge/L2ERC20Bridge.sol rename to l2-contracts/contracts/bridge/L2ERC20Bridge.sol diff --git a/zksync/contracts/bridge/L2StandardERC20.sol b/l2-contracts/contracts/bridge/L2StandardERC20.sol similarity index 100% rename from zksync/contracts/bridge/L2StandardERC20.sol rename to l2-contracts/contracts/bridge/L2StandardERC20.sol diff --git a/zksync/contracts/bridge/L2Weth.sol b/l2-contracts/contracts/bridge/L2Weth.sol similarity index 100% rename from zksync/contracts/bridge/L2Weth.sol rename to l2-contracts/contracts/bridge/L2Weth.sol diff --git a/zksync/contracts/bridge/L2WethBridge.sol b/l2-contracts/contracts/bridge/L2WethBridge.sol similarity index 100% rename from zksync/contracts/bridge/L2WethBridge.sol rename to l2-contracts/contracts/bridge/L2WethBridge.sol diff --git a/zksync/contracts/bridge/interfaces/IL1Bridge.sol b/l2-contracts/contracts/bridge/interfaces/IL1Bridge.sol similarity index 100% rename from zksync/contracts/bridge/interfaces/IL1Bridge.sol rename to l2-contracts/contracts/bridge/interfaces/IL1Bridge.sol diff --git a/zksync/contracts/bridge/interfaces/IL2Bridge.sol b/l2-contracts/contracts/bridge/interfaces/IL2Bridge.sol similarity index 100% rename from zksync/contracts/bridge/interfaces/IL2Bridge.sol rename to l2-contracts/contracts/bridge/interfaces/IL2Bridge.sol diff --git a/zksync/contracts/bridge/interfaces/IL2StandardToken.sol b/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol similarity index 100% rename from zksync/contracts/bridge/interfaces/IL2StandardToken.sol rename to l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol diff --git a/zksync/contracts/bridge/interfaces/IL2Weth.sol b/l2-contracts/contracts/bridge/interfaces/IL2Weth.sol similarity index 100% rename from zksync/contracts/bridge/interfaces/IL2Weth.sol rename to l2-contracts/contracts/bridge/interfaces/IL2Weth.sol diff --git a/zksync/contracts/interfaces/IPaymaster.sol b/l2-contracts/contracts/interfaces/IPaymaster.sol similarity index 100% rename from zksync/contracts/interfaces/IPaymaster.sol rename to l2-contracts/contracts/interfaces/IPaymaster.sol diff --git a/zksync/contracts/interfaces/IPaymasterFlow.sol b/l2-contracts/contracts/interfaces/IPaymasterFlow.sol similarity index 100% rename from zksync/contracts/interfaces/IPaymasterFlow.sol rename to l2-contracts/contracts/interfaces/IPaymasterFlow.sol diff --git a/zksync/contracts/vendor/AddressAliasHelper.sol b/l2-contracts/contracts/vendor/AddressAliasHelper.sol similarity index 100% rename from zksync/contracts/vendor/AddressAliasHelper.sol rename to l2-contracts/contracts/vendor/AddressAliasHelper.sol diff --git a/zksync/hardhat.config.ts b/l2-contracts/hardhat.config.ts similarity index 82% rename from zksync/hardhat.config.ts rename to l2-contracts/hardhat.config.ts index 6c7a073bc..908567be8 100644 --- a/zksync/hardhat.config.ts +++ b/l2-contracts/hardhat.config.ts @@ -13,7 +13,7 @@ if (!process.env.CHAIN_ETH_NETWORK) { export default { zksolc: { - version: "1.3.14", + version: "1.3.18", compilerSource: "binary", settings: { isSystem: true, @@ -37,6 +37,13 @@ export default { // contract verification endpoint verifyURL: "https://zksync2-testnet-explorer.zksync.dev/contract_verification", }, + zkSyncTestnetSepolia: { + url: "https://sepolia.era.zksync.dev", + ethNetwork: "sepolia", + zksync: true, + // contract verification endpoint + verifyURL: "https://explorer.sepolia.era.zksync.dev/contract_verification", + }, zksyncMainnet: { url: "https://mainnet.era.zksync.io", ethNetwork: "mainnet", diff --git a/zksync/package.json b/l2-contracts/package.json similarity index 58% rename from zksync/package.json rename to l2-contracts/package.json index fbd13450e..b45b988a9 100644 --- a/zksync/package.json +++ b/l2-contracts/package.json @@ -1,13 +1,11 @@ { - "name": "l2-zksync-contracts", + "name": "l2-contracts", "version": "0.1.0", "license": "MIT", "devDependencies": { - "@matterlabs/eslint-config-typescript": "^1.1.2", "@matterlabs/hardhat-zksync-deploy": "^0.6.5", "@matterlabs/hardhat-zksync-solc": "^0.3.15", "@matterlabs/hardhat-zksync-verify": "^0.2.0", - "@matterlabs/prettier-config": "^1.0.3", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.4", "@nomicfoundation/hardhat-verify": "^1.1.0", @@ -20,24 +18,14 @@ "@types/chai": "^4.2.21", "@types/chai-as-promised": "^7.1.4", "@types/mocha": "^8.2.3", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "@typescript-eslint/parser": "^6.7.4", "chai": "^4.3.4", "chai-as-promised": "^7.1.1", "chalk": "^4.1.0", "commander": "^6.0.0", - "eslint": "^8.51.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.0", - "eslint-plugin-prettier": "^5.0.1", "ethers": "^5.7.0", - "hardhat": "=2.16.0", + "hardhat": "^2.18.3", "hardhat-typechain": "^0.3.3", - "markdownlint-cli": "^0.33.0", "mocha": "^9.0.2", - "prettier": "^3.0.3", - "prettier-plugin-solidity": "^1.1.3", - "solhint": "^3.6.2", "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^5.2.2", @@ -46,19 +34,13 @@ "scripts": { "build": "hardhat compile", "clean": "hardhat clean", - "lint:check": "yarn lint:md && yarn lint:sol && yarn lint:ts && yarn prettier:check", - "lint:fix": "yarn lint:md --fix && yarn lint:sol --fix && yarn lint:ts --fix && yarn prettier:fix", - "lint:md": "markdownlint \"**/*.md\"", - "lint:sol": "solhint \"**/*.sol\"", - "lint:ts": "eslint .", - "prettier:check": "prettier --check \"**/*.{js,json,md,sol,ts,yaml}\"", - "prettier:fix": "prettier --write \"**/*.{js,json,md,sol,ts,yaml}\"", + "test": "hardhat test", "verify": "hardhat run src/verify.ts", "deploy-testnet-paymaster": "ts-node src/deployTestnetPaymaster.ts", "deploy-force-deploy-upgrader": "ts-node src/deployForceDeployUpgrader.ts", "publish-bridge-preimages": "ts-node src/publish-bridge-preimages.ts", "deploy-l2-weth": "ts-node src/deployL2Weth.ts", - "upgrade-l2-erc20-contract": "ts-node src/upgradeL2BridgeImpl.ts" + "upgrade-bridge-contracts": "ts-node src/upgradeBridgeImpl.ts" }, "dependencies": { "dotenv": "^16.0.3" diff --git a/zksync/src/deployForceDeployUpgrader.ts b/l2-contracts/src/deployForceDeployUpgrader.ts similarity index 96% rename from zksync/src/deployForceDeployUpgrader.ts rename to l2-contracts/src/deployForceDeployUpgrader.ts index 0ae390d1e..88a142073 100644 --- a/zksync/src/deployForceDeployUpgrader.ts +++ b/l2-contracts/src/deployForceDeployUpgrader.ts @@ -1,7 +1,7 @@ import { Command } from "commander"; import { ethers, Wallet } from "ethers"; import { computeL2Create2Address, create2DeployFromL1, getNumberFromEnv } from "./utils"; -import { web3Provider } from "../../ethereum/scripts/utils"; +import { web3Provider } from "../../l1-contracts/scripts/utils"; import * as fs from "fs"; import * as path from "path"; import * as hre from "hardhat"; @@ -23,7 +23,7 @@ async function main() { .name("deploy-force-deploy-upgrader") .description("Deploys the force deploy upgrader contract to L2"); - program.option("--private-key ").action(async (cmd: Command) => { + program.option("--private-key ").action(async (cmd) => { const deployWallet = cmd.privateKey ? new Wallet(cmd.privateKey, provider) : Wallet.fromMnemonic( diff --git a/zksync/src/deployL2Weth.ts b/l2-contracts/src/deployL2Weth.ts similarity index 94% rename from zksync/src/deployL2Weth.ts rename to l2-contracts/src/deployL2Weth.ts index ac9e8c17b..017f314bd 100644 --- a/zksync/src/deployL2Weth.ts +++ b/l2-contracts/src/deployL2Weth.ts @@ -1,10 +1,10 @@ import { Command } from "commander"; import { ethers, Wallet } from "ethers"; -import { Deployer } from "../../ethereum/src.ts/deploy"; import { formatUnits, parseUnits } from "ethers/lib/utils"; -import { getTokens, web3Provider } from "../../ethereum/scripts/utils"; +import { getTokens, web3Provider } from "../../l1-contracts/scripts/utils"; +import { Deployer } from "../../l1-contracts/src.ts/deploy"; -import { getNumberFromEnv, applyL1ToL2Alias, create2DeployFromL1, computeL2Create2Address } from "./utils"; +import { applyL1ToL2Alias, computeL2Create2Address, create2DeployFromL1, getNumberFromEnv } from "./utils"; import * as fs from "fs"; import * as path from "path"; @@ -13,7 +13,7 @@ const provider = web3Provider(); const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant"); const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); -const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/zksync/artifacts-zk/"); +const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/l2-contracts/artifacts-zk/"); const l2BridgeArtifactsPath = path.join(contractArtifactsPath, "cache-zk/solpp-generated-contracts/bridge/"); const openzeppelinTransparentProxyArtifactsPath = path.join( diff --git a/zksync/src/deployTestnetPaymaster.ts b/l2-contracts/src/deployTestnetPaymaster.ts similarity index 96% rename from zksync/src/deployTestnetPaymaster.ts rename to l2-contracts/src/deployTestnetPaymaster.ts index 903d384c7..d1f35e0ee 100644 --- a/zksync/src/deployTestnetPaymaster.ts +++ b/l2-contracts/src/deployTestnetPaymaster.ts @@ -1,7 +1,7 @@ import { Command } from "commander"; import { ethers, Wallet } from "ethers"; import { computeL2Create2Address, create2DeployFromL1, getNumberFromEnv } from "./utils"; -import { web3Provider } from "../../ethereum/scripts/utils"; +import { web3Provider } from "../../l1-contracts/scripts/utils"; import * as fs from "fs"; import * as path from "path"; import * as hre from "hardhat"; @@ -20,7 +20,7 @@ async function main() { program.version("0.1.0").name("deploy-testnet-paymaster").description("Deploys the testnet paymaster to L2"); - program.option("--private-key ").action(async (cmd: Command) => { + program.option("--private-key ").action(async (cmd) => { const deployWallet = cmd.privateKey ? new Wallet(cmd.privateKey, provider) : Wallet.fromMnemonic( diff --git a/zksync/src/publish-bridge-preimages.ts b/l2-contracts/src/publish-bridge-preimages.ts similarity index 93% rename from zksync/src/publish-bridge-preimages.ts rename to l2-contracts/src/publish-bridge-preimages.ts index 2ef0a98d6..3f9b97732 100644 --- a/zksync/src/publish-bridge-preimages.ts +++ b/l2-contracts/src/publish-bridge-preimages.ts @@ -1,9 +1,9 @@ import { Command } from "commander"; import { Wallet, ethers } from "ethers"; import * as fs from "fs"; -import { Deployer } from "../../ethereum/src.ts/deploy"; +import { Deployer } from "../../l1-contracts/src.ts/deploy"; import * as path from "path"; -import { getNumberFromEnv, web3Provider } from "../../ethereum/scripts/utils"; +import { getNumberFromEnv, web3Provider } from "../../l1-contracts/scripts/utils"; import * as hre from "hardhat"; import { REQUIRED_L2_GAS_PRICE_PER_PUBDATA } from "./utils"; diff --git a/zksync/src/upgradeL2BridgeImpl.ts b/l2-contracts/src/upgradeBridgeImpl.ts similarity index 70% rename from zksync/src/upgradeL2BridgeImpl.ts rename to l2-contracts/src/upgradeBridgeImpl.ts index 25f05e2a7..3484aeed5 100644 --- a/zksync/src/upgradeL2BridgeImpl.ts +++ b/l2-contracts/src/upgradeBridgeImpl.ts @@ -1,33 +1,63 @@ -import * as hre from "hardhat"; import "@nomiclabs/hardhat-ethers"; import { Command } from "commander"; -import type { BigNumber } from "ethers"; -import { Wallet, ethers } from "ethers"; +import { Wallet, ethers, BigNumber } from "ethers"; import * as fs from "fs"; +import * as hre from "hardhat"; import * as path from "path"; import { Provider } from "zksync-web3"; import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-web3/build/src/utils"; -import { getAddressFromEnv, getNumberFromEnv, web3Provider } from "../../ethereum/scripts/utils"; -import { Deployer } from "../../ethereum/src.ts/deploy"; -import { awaitPriorityOps, computeL2Create2Address, create2DeployFromL1 } from "./utils"; +import { getAddressFromEnv, getNumberFromEnv, web3Provider } from "../../l1-contracts/scripts/utils"; +import { Deployer } from "../../l1-contracts/src.ts/deploy"; +import { awaitPriorityOps, computeL2Create2Address, create2DeployFromL1, getL1TxInfo } from "./utils"; + +const SupportedL2Contracts = ["L2ERC20Bridge", "L2StandardERC20", "L2WethBridge", "L2Weth"] as const; + +// For L1 contracts we can not read bytecodes, but we can still produce the upgrade calldata +const SupportedL1Contracts = ["L1ERC20Bridge"] as const; + +const SupportedContracts = [...SupportedL1Contracts, ...SupportedL2Contracts] as const; -export function getContractBytecode(contractName: string) { +type SupportedL2Contract = (typeof SupportedL2Contracts)[number]; +type SupportedContract = (typeof SupportedContracts)[number]; + +interface UpgradeInfo { + contract: SupportedContract; + target: string; + l2ProxyAddress?: string; +} + +export function getContractBytecode(contractName: SupportedL2Contract) { return hre.artifacts.readArtifactSync(contractName).bytecode; } -type SupportedContracts = "L2ERC20Bridge" | "L2StandardERC20" | "L2WethBridge" | "L2Weth"; // eslint-disable-next-line @typescript-eslint/no-explicit-any -function checkSupportedContract(contract: any): contract is SupportedContracts { - if (!["L2ERC20Bridge", "L2StandardERC20", "L2WethBridge", "L2Weth"].includes(contract)) { +function checkSupportedL2Contract(contract: any): contract is SupportedL2Contract { + if (!SupportedL2Contracts.includes(contract)) { throw new Error(`Unsupported contract: ${contract}`); } return true; } -const priorityTxMaxGasLimit = getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT"); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function checkSupportedContract(contract: any): contract is SupportedContract { + if (!SupportedContracts.includes(contract)) { + throw new Error(`Unsupported contract: ${contract}`); + } + + return true; +} + +function validateUpgradeInfo(info: UpgradeInfo) { + if (!info.target) { + throw new Error("L2 target address is not provided"); + } + checkSupportedContract(info.contract); +} + +const priorityTxMaxGasLimit = BigNumber.from(getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT")); const l2Erc20BridgeProxyAddress = getAddressFromEnv("CONTRACTS_L2_ERC20_BRIDGE_ADDR"); -const l2WethProxyAddress = getAddressFromEnv("CONTRACTS_L2_WETH_TOKEN_PROXY_ADDR"); +const l1Erc20BridgeProxyAddress = getAddressFromEnv("CONTRACTS_L1_ERC20_BRIDGE_PROXY_ADDR"); const EIP1967_IMPLEMENTATION_SLOT = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; const provider = web3Provider(); @@ -98,13 +128,21 @@ async function getL1TxInfo( async function getTransparentProxyUpgradeTxInfo( deployer: Deployer, - proxyAddress: string, target: string, + proxyAddress: string, refundRecipient: string, gasPrice: BigNumber ) { const l2Calldata = await getTransparentProxyUpgradeCalldata(target); - return await getL1TxInfo(deployer, proxyAddress, l2Calldata, refundRecipient, gasPrice); + return await getL1TxInfo( + deployer, + proxyAddress, + l2Calldata, + refundRecipient, + gasPrice, + priorityTxMaxGasLimit, + provider + ); } async function getTokenBeaconUpgradeTxInfo( @@ -116,7 +154,15 @@ async function getTokenBeaconUpgradeTxInfo( ) { const l2Calldata = await getBeaconProxyUpgradeCalldata(target); - return await getL1TxInfo(deployer, proxy, l2Calldata, refundRecipient, gasPrice); + return await getL1TxInfo(deployer, proxy, l2Calldata, refundRecipient, gasPrice, priorityTxMaxGasLimit, provider); +} + +async function getL1BridgeUpgradeTxInfo(proxyTarget: string) { + return { + target: l1Erc20BridgeProxyAddress, + value: 0, + data: await getTransparentProxyUpgradeCalldata(proxyTarget), + }; } async function getTxInfo( @@ -124,13 +170,21 @@ async function getTxInfo( target: string, refundRecipient: string, gasPrice: BigNumber, - contract: SupportedContracts, + contract: SupportedContract, l2ProxyAddress?: string ) { if (contract === "L2ERC20Bridge") { - return getTransparentProxyUpgradeTxInfo(deployer, target, l2Erc20BridgeProxyAddress, refundRecipient, gasPrice); + return await getTransparentProxyUpgradeTxInfo( + deployer, + target, + l2Erc20BridgeProxyAddress, + refundRecipient, + gasPrice + ); } else if (contract == "L2Weth") { - return getTransparentProxyUpgradeTxInfo(deployer, target, l2WethProxyAddress, refundRecipient, gasPrice); + throw new Error( + "The latest L2Weth implementation requires L2WethBridge to be deployed in order to be correctly initialized, which is not the case on the majority of networks. Remove this error once the bridge is deployed." + ); } else if (contract == "L2StandardERC20") { if (!l2ProxyAddress) { console.log("Explicit beacon address is not supplied, requesting the one from L2 node"); @@ -138,7 +192,9 @@ async function getTxInfo( } console.log(`Using beacon address: ${l2ProxyAddress}`); - return getTokenBeaconUpgradeTxInfo(deployer, target, refundRecipient, gasPrice, l2ProxyAddress); + return await getTokenBeaconUpgradeTxInfo(deployer, target, refundRecipient, gasPrice, l2ProxyAddress); + } else if (contract == "L1ERC20Bridge") { + return await getL1BridgeUpgradeTxInfo(target); } else { throw new Error(`Unsupported contract: ${contract}`); } @@ -150,7 +206,7 @@ async function main() { program.version("0.1.0").name("upgrade-l2-bridge-impl"); program - .command("deploy-target") + .command("deploy-l2-target") .option("--contract ") .option("--private-key ") .option("--gas-price ") @@ -169,7 +225,7 @@ async function main() { ? ethers.utils.parseUnits(cmd.gasPrice, "gwei") : (await provider.getGasPrice()).mul(3).div(2); const salt = cmd.create2Salt ? cmd.create2Salt : ethers.utils.hexlify(ethers.constants.HashZero); - checkSupportedContract(cmd.contract); + checkSupportedL2Contract(cmd.contract); console.log(`Using deployer wallet: ${deployWallet.address}`); console.log("Gas price: ", ethers.utils.formatUnits(gasPrice, "gwei")); @@ -235,9 +291,7 @@ async function main() { program .command("prepare-l1-tx-info") - .option("--contract ") - .option("--target-address ") - .option("--l2-proxy-address ") + .option("--upgrades-info ") .option("--gas-price ") .option("--deployer-private-key ") .option("--refund-recipient ") @@ -252,72 +306,56 @@ async function main() { "m/44'/60'/0'/0/1" ).connect(provider); const deployer = new Deployer({ deployWallet }); - const target = cmd.targetAddress as string; - if (!target) { - throw new Error("L2 target address is not provided"); - } - checkSupportedContract(cmd.contract); - const refundRecipient = cmd.refundRecipient ? cmd.refundRecipient : deployWallet.address; console.log("Gas price: ", ethers.utils.formatUnits(gasPrice, "gwei")); - console.log("Target address: ", target); - console.log("Refund recipient: ", refundRecipient); - const txInfo = await getTxInfo(deployer, target, refundRecipient, gasPrice, cmd.contract, cmd.l2ProxyAddress); + console.log( + "IMPORTANT: gasPrice that you provide in the transaction should be <= to the one provided to this tool." + ); - console.log(JSON.stringify(txInfo, null, 4)); - console.log("IMPORTANT: gasPrice that you provide in the transaction should <= to the one provided above."); - }); + console.log("Refund recipient: ", refundRecipient); - program - .command("instant-upgrade") - .option("--contract ") - .option("--target-address ") - .option("--l2-proxy-address ") - .option("--gas-price ") - .option("--governor-private-key ") - .option("--refund-recipient ") - .option("--no-l2-double-check") - .action(async (cmd) => { - const gasPrice = cmd.gasPrice - ? ethers.utils.parseUnits(cmd.gasPrice, "gwei") - : (await provider.getGasPrice()).mul(3).div(2); - const deployWallet = cmd.governorPrivateKey - ? new Wallet(cmd.governorPrivateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - const deployer = new Deployer({ deployWallet }); - const target = cmd.targetAddress as string; - if (!target) { - throw new Error("L2 target address is not provided"); + const ugpradesInfo = JSON.parse(cmd.upgradesInfo) as UpgradeInfo[]; + ugpradesInfo.forEach(validateUpgradeInfo); + + const governanceCalls = []; + for (const info of ugpradesInfo) { + console.log("Generating upgrade transaction for contract: ", info.contract); + console.log("Target address: ", info.target); + const txInfo = await getTxInfo( + deployer, + info.target, + refundRecipient, + gasPrice, + info.contract, + info.l2ProxyAddress + ); + + console.log(JSON.stringify(txInfo, null, 4) + "\n"); + + governanceCalls.push(txInfo); } - checkSupportedContract(cmd.contract); - const refundRecipient = cmd.refundRecipient ? cmd.refundRecipient : deployWallet.address; - console.log(`Using deployer wallet: ${deployWallet.address}`); - console.log("Gas price: ", ethers.utils.formatUnits(gasPrice, "gwei")); - console.log("Target address: ", target); - console.log("Refund recipient: ", refundRecipient); + const operation = { + calls: governanceCalls, + predecessor: ethers.constants.HashZero, + salt: ethers.constants.HashZero, + }; - const txInfo = await getTxInfo(deployer, target, refundRecipient, gasPrice, cmd.contract, cmd.l2ProxyAddress); - const tx = await deployWallet.sendTransaction(txInfo); - console.log("L1 tx hash: ", tx.hash); + console.log("Combined list of governance calls: "); + console.log(JSON.stringify(operation, null, 4) + "\n"); - const receipt = await tx.wait(); - if (receipt.status !== 1) { - console.error("L1 tx failed"); - process.exit(1); - } + const governance = deployer.governanceContract(deployWallet); + const scheduleTransparentCalldata = governance.interface.encodeFunctionData("scheduleTransparent", [ + operation, + 0, + ]); + const executeCalldata = governance.interface.encodeFunctionData("execute", [operation]); - // Double checking that the upgrade has been successful on L2. - // Note that it requires working L2 node. - if (cmd.l2DoubleCheck !== false) { - const zksProvider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); - await awaitPriorityOps(zksProvider, receipt, deployer.zkSyncContract(deployWallet).interface); + console.log("scheduleTransparentCalldata: "); + console.log(scheduleTransparentCalldata); - console.log("The L2 transaction has been successfully committed"); - } + console.log("executeCalldata: "); + console.log(executeCalldata); }); program.command("get-l2-erc20-beacon-address").action(async () => { diff --git a/zksync/src/utils.ts b/l2-contracts/src/utils.ts similarity index 79% rename from zksync/src/utils.ts rename to l2-contracts/src/utils.ts index d59c46416..3224d6d68 100644 --- a/zksync/src/utils.ts +++ b/l2-contracts/src/utils.ts @@ -1,13 +1,14 @@ import { artifacts } from "hardhat"; import { Interface } from "ethers/lib/utils"; -import { deployedAddressesFromEnv } from "../../ethereum/src.ts/deploy"; -import { IZkSyncFactory } from "../../ethereum/typechain/IZkSyncFactory"; +import type { Deployer } from "../../l1-contracts/src.ts/deploy"; +import { deployedAddressesFromEnv } from "../../l1-contracts/src.ts/deploy"; +import { IZkSyncFactory } from "../../l1-contracts/typechain/IZkSyncFactory"; -import type { BytesLike, Wallet } from "ethers"; +import type { BigNumber, BytesLike, Wallet } from "ethers"; import { ethers } from "ethers"; import type { Provider } from "zksync-web3"; -import { sleep } from "zksync-web3/build/src/utils"; +import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, sleep } from "zksync-web3/build/src/utils"; // eslint-disable-next-line @typescript-eslint/no-var-requires export const REQUIRED_L2_GAS_PRICE_PER_PUBDATA = require("../../SystemConfig.json").REQUIRED_L2_GAS_PRICE_PER_PUBDATA; @@ -133,3 +134,36 @@ export async function awaitPriorityOps( } } } + +export async function getL1TxInfo( + deployer: Deployer, + to: string, + l2Calldata: string, + refundRecipient: string, + gasPrice: BigNumber, + priorityTxMaxGasLimit: BigNumber, + provider: ethers.providers.JsonRpcProvider +) { + const zksync = deployer.zkSyncContract(ethers.Wallet.createRandom().connect(provider)); + const l1Calldata = zksync.interface.encodeFunctionData("requestL2Transaction", [ + to, + 0, + l2Calldata, + priorityTxMaxGasLimit, + REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, + [], // It is assumed that the target has already been deployed + refundRecipient, + ]); + + const neededValue = await zksync.l2TransactionBaseCost( + gasPrice, + priorityTxMaxGasLimit, + REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT + ); + + return { + target: zksync.address, + data: l1Calldata, + value: neededValue.toString(), + }; +} diff --git a/zksync/src/verify.ts b/l2-contracts/src/verify.ts similarity index 100% rename from zksync/src/verify.ts rename to l2-contracts/src/verify.ts diff --git a/zksync/test/weth.test.ts b/l2-contracts/test/weth.test.ts similarity index 100% rename from zksync/test/weth.test.ts rename to l2-contracts/test/weth.test.ts diff --git a/zksync/tsconfig.json b/l2-contracts/tsconfig.json similarity index 100% rename from zksync/tsconfig.json rename to l2-contracts/tsconfig.json diff --git a/package.json b/package.json new file mode 100644 index 000000000..5d22b96d9 --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "era-contracts", + "version": "0.1.0", + "private": true, + "workspaces": [ + "l1-contracts", + "l2-contracts", + "system-contracts" + ], + "devDependencies": { + "@matterlabs/eslint-config-typescript": "^1.1.2", + "@matterlabs/prettier-config": "^1.0.3", + "@typescript-eslint/eslint-plugin": "^6.7.4", + "@typescript-eslint/parser": "^6.7.4", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint": "^8.51.0", + "markdownlint-cli": "^0.33.0", + "prettier-plugin-solidity": "^1.1.3", + "prettier": "^3.0.3", + "solhint": "^3.6.2" + }, + "scripts": { + "lint:check": "yarn lint:md && yarn lint:sol && yarn lint:ts && yarn prettier:check", + "lint:fix": "yarn lint:md --fix && yarn lint:sol --fix && yarn lint:ts --fix && yarn prettier:fix", + "lint:md": "markdownlint \"**/*.md\"", + "lint:sol": "solhint \"**/*.sol\"", + "lint:ts": "eslint .", + "prettier:check": "prettier --check \"**/*.{js,json,md,sol,ts,yaml}\"", + "prettier:fix": "prettier --write \"**/*.{js,json,md,sol,ts,yaml}\"", + "l1": "yarn workspace l1-contracts", + "l2": "yarn workspace l2-contracts", + "sc": "yarn workspace system-contracts" + } +} diff --git a/system-contracts/README.md b/system-contracts/README.md new file mode 100644 index 000000000..1449c936f --- /dev/null +++ b/system-contracts/README.md @@ -0,0 +1,172 @@ +# zkSync Era: System Contracts + +[![Logo](../eraLogo.svg)](https://zksync.io/) + +zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring +or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +write smart contracts in C++, Rust and other popular languages. + +## system-contracts + +To keep the zero-knowledge circuits as simple as possible and enable simple extensions, we created the system contracts. +These are privileged special-purpose contracts that instantiate some recurring actions on the protocol level. Some of +the most commonly used contracts: + +`ContractDeployer` This contract is used to deploy new smart contracts. Its job is to make sure that the bytecode for +each deployed contract is known. This contract also defines the derivation address. Whenever a contract is deployed, a +ContractDeployed event is emitted. + +`L1Messenger` This contract is used to send messages from zkSync to Ethereum. For each message sent, the L1MessageSent +event is emitted. + +`NonceHolder` This contract stores account nonces. The account nonces are stored in a single place for efficiency (the +tx nonce and the deployment nonce are stored in a single place) and also for the ease of the operator. + +`Bootloader` For greater extensibility and to lower the overhead, some parts of the protocol (e.g. account abstraction +rules) were moved to an ephemeral contract called a bootloader. + +We call it ephemeral because it is not physically deployed and cannot be called, but it has a formal address that is +used on msg.sender, when it calls other contracts. + +## Building + +This repository is used as a submodule of the [zksync-era](https://github.com/matter-labs/zksync-era). + +Compile the solidity and yul contracts: `yarn sc build` + +Check the system contracts hashes: `yarn sc calculate-hashes:check` + +Update the system contracts hashes: `yarn sc calculate-hashes:fix` + +## Testing + +### Run tests + +The tests of the system contracts utilize the zkSync test node. In order to run the tests, execute the following commands in the root of the repository: + +``` +yarn test-node +``` + +It will run the test node, and you can see its logs in the output. +Then run tests in the separate terminal: + +``` +yarn test +``` + +Please note that you need to rerun the test node every time you are running the tests because, in the current version, tests will be affected by the state after the previous run. + +### Testing infrastructure overview + +#### Address space + +During the tests, we deploy most of the system contracts on special "testing" addresses, which are equal to production addresses + `0x1000`. + +This approach enhances test flexibility since we can manipulate contract states without impacting the system's functionality. +We can freely modify contract states, mock them, etc., without being constrained by the contracts used by the test node. +Additionally, these addresses are located in the kernel space, as required by the system contracts. + +For this purpose special testing preprocessing mode exists, it's needed to change the address constants. +When some system contracts call others using these constants, they will actually get to testing addresses. + +The exceptions are: + +- [EventWriter.yul](contracts%2FEventWriter.yul) +- [precompiles](contracts%2Fprecompiles) + +During preprocessing, we keep production addresses for them because we want other contracts to call them in tests rather than mock them. This simplifies the testing process. +Also, when testing these contracts, some of them should also be deployed on the original addresses: + +- [EventWriter.yul](contracts%2FEventWriter.yul): should be on the original address because event logs are filtered by address +- [Ecrecover.yul](contracts%2Fprecompiles%2FEcrecover.yul): uses precompile call instruction, which is address-dependent +- [Keccak256.yul](contracts%2Fprecompiles%2FKeccak256.yul): uses precompile call instruction, which is address-dependent +- [SHA256.yul](contracts%2Fprecompiles%2FSHA256.yul): uses precompile call instruction, which is address-dependent + +However, this is not the case for [EcAdd.yul](contracts%2Fprecompiles%2FEcAdd.yul) and [EcMul.yul](contracts%2Fprecompiles%2FEcMul.yul), so they can be deployed on any addresses, even outside kernel space. + +#### Test contracts/features + +The behavior of the contracts can depend on various factors: system call flag, extra ABI registers, `msg.sender`, `msg.value`(`context_u128` value), context, etc. +It is crucial to control these values during testing. + +They are often interconnected, requiring the need to mock some of them. + +To achieve this, the following contracts and features were used/implemented: + +- [MockContract.sol](contracts%2Ftest-contracts%2FMockContract.sol) - a contract used for mocking. +- [ExtraAbiCaller.zasm](contracts%2Ftest-contracts%2FExtraAbiCaller.zasm) - a contract that allows to set the extra abi registers, `context_u128` value with the system flag for the call. +- [SystemCaller.sol](contracts%2Ftest-contracts%2FSystemCaller.sol) - a "proxy" that sets the system call flag. + In theory `ExtraAbiCaller` can be used instead, but this one is sometimes more convenient because it can be called with the destination contract ABI. +- `hardhat_stopImpersonatingAccount` - this API method is useful during the tests themselves. + Apart from that, it's used to force deploy the contracts on the specific addresses during the tests. See [ContractDeployer.sol](contracts%2FContractDeployer.sol):`forceDeployOnAddress`. + +Only the main and most generic aspects are mentioned above, however, there are more features that can be found in the tests. +There are wrappers/helpers for these contracts and features, along with additional functionality in [shared](test%2Fshared), and [test-contracts](contracts%2Ftest-contracts). + +#### Test cases + +Currently, during specific contract testing, we aim to cover all external functions. +Typically, one test case corresponds to one main function call, possibly with additional calls to prepare the state. + +Therefore, considering all the information above, we can say that it's almost unit tests over external functions. +Many examples can be found in [test](test). + +## Update Process + +System contracts handle core functionalities and play a critical role in maintaining the integrity of our protocol. To +ensure the highest level of security and reliability, these system contracts undergo an audit before any release. + +Here is an overview of the release process of the system contracts which is aimed to preserve agility and clarity on the +order of the upgrades: + +### `main` branch + +The `main` branch contains the latest code that is ready to be deployed into production. It reflects the most stable and +audited version of the protocol. + +### `dev` branch + +The `dev` branch is for active development & the latest code changes. Whenever a new PR with system contract changes is +created it should be based on the `dev` branch. + +### Creating a new release + +Whenever a new release is planned, a new branch named `release-vX-` should be created off the `dev` branch, where +`X` represents the release version, and `` is a short descriptive name for the release. The PR with the new +release should point to either the `main` branch or to the release branch with a lower version (in case the previous +branch has not been merged into `main` for some reason). + +Once the audit for the release branch is complete and all the fixes from the audit are applied, we need to merge the new +changes into the `dev` branch. Once the release is final and merged into the `main` branch, the `main` branch should be +merged back into the `dev` branch to keep it up-to-date. + +### Updating Unaudited Code + +Since scripts, READMEs, etc., are code that is not subject to audits, these are to be merged directly into the `main` +branch. The rest of the release branches as well as the `dev` branch should merge `main` to synchronize with these +changes. + +## License + +The zkSync Era system-contracts are distributed under the terms of the MIT license. + +See [LICENSE-MIT](LICENSE-MIT) for details. + +## Official Links + +- [Website](https://zksync.io/) +- [GitHub](https://github.com/matter-labs) +- [ZK Credo](https://github.com/zksync/credo) +- [Twitter](https://twitter.com/zksync) +- [Twitter for Devs](https://twitter.com/zkSyncDevs) +- [Discord](https://join.zksync.dev/) +- [Mirror](https://zksync.mirror.xyz/) + +## Disclaimer + +zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! +It is important to state that forking it now can potentially lead to missing important security updates, critical +features, and performance improvements. diff --git a/system-contracts/SystemConfig.json b/system-contracts/SystemConfig.json new file mode 100644 index 000000000..827e11b5b --- /dev/null +++ b/system-contracts/SystemConfig.json @@ -0,0 +1,17 @@ +{ + "GUARANTEED_PUBDATA_BYTES": 4000, + "MAX_PUBDATA_PER_BATCH": 110000, + "MAX_TRANSACTIONS_IN_BATCH": 1024, + "BATCH_OVERHEAD_L2_GAS": 1200000, + "BATCH_OVERHEAD_L1_GAS": 1000000, + "L2_TX_INTRINSIC_GAS": 14070, + "L2_TX_INTRINSIC_PUBDATA": 0, + "L1_TX_INTRINSIC_L2_GAS": 167157, + "L1_TX_INTRINSIC_PUBDATA": 88, + "MAX_GAS_PER_TRANSACTION": 80000000, + "BOOTLOADER_MEMORY_FOR_TXS": 8740224, + "REFUND_GAS": 7343, + "KECCAK_ROUND_COST_GAS": 40, + "SHA256_ROUND_COST_GAS": 7, + "ECRECOVER_COST_GAS": 1112 +} diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json new file mode 100644 index 000000000..50947815d --- /dev/null +++ b/system-contracts/SystemContractsHashes.json @@ -0,0 +1,177 @@ +[ + { + "contractName": "AccountCodeStorage", + "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", + "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", + "bytecodeHash": "0x01000075c32c6af70ed4fd798a3fca41f2984e7440e2d2937858d700637e0655", + "sourceCodeHash": "0xa4bb031f7c6e95044b3c69f15107141d8ee4f2fd637986955f3d5bde4444ff3f" + }, + { + "contractName": "BootloaderUtilities", + "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", + "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", + "bytecodeHash": "0x010007c95cdffb79ed99ad5fb842d3bab4084e2d49028df8ee3f7c2d543f7ebe", + "sourceCodeHash": "0x062142deed9240bc852c7657dc3e90051a9ff10366436e9af6b2b625b4f8115d" + }, + { + "contractName": "ComplexUpgrader", + "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", + "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", + "bytecodeHash": "0x01000055de10df9214a2628ab870a3bc2154a6e7f8c0479a7bad15c875aec050", + "sourceCodeHash": "0x0aa5d7ed159e783acde47856b13801b7f2268ba39b2fa50807fe3d705c506e96" + }, + { + "contractName": "Compressor", + "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", + "sourceCodePath": "contracts-preprocessed/Compressor.sol", + "bytecodeHash": "0x010001670943abd41e5b14499ae7bd0b99406a7d3cc406d9251c138d87f573c0", + "sourceCodeHash": "0x25ff4b50b5373f4fed1ae95f461a4547bb45bf5255ca94d8645b046aaab026a6" + }, + { + "contractName": "ContractDeployer", + "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", + "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", + "bytecodeHash": "0x0100055578bdf1a737843d2278c672bfa9be2c17183a7e9b00052845aa5d240a", + "sourceCodeHash": "0xa7f1866a623eea8567752f870098fd77151533782614e01ba7e0e1796ba224a1" + }, + { + "contractName": "DefaultAccount", + "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", + "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", + "bytecodeHash": "0x0100055bf7f1bc4237c2be24252fb6737cc235194139e544933c1dbf25c24ee8", + "sourceCodeHash": "0x7f7c2dc241f593353aea2eb4f42b3365d620b02a5c69d1359eca80c356b628f9" + }, + { + "contractName": "EmptyContract", + "bytecodePath": "artifacts-zk/contracts-preprocessed/EmptyContract.sol/EmptyContract.json", + "sourceCodePath": "contracts-preprocessed/EmptyContract.sol", + "bytecodeHash": "0x01000007f845e3f2ab16646632231e4fee11627449b45067fa0e7c76ba114d06", + "sourceCodeHash": "0x8b1a0053bc33f370c64407132f669010a5733183f146dfe24f4568915b463a61" + }, + { + "contractName": "ImmutableSimulator", + "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", + "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", + "bytecodeHash": "0x0100003d467f114197fad7d1e6bb58867710524d5c8d200558a213f5429cbf84", + "sourceCodeHash": "0xf822a87c1f373843609ce920f6b685023c88f15a1de100d0989d980c031314cb" + }, + { + "contractName": "KnownCodesStorage", + "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", + "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", + "bytecodeHash": "0x0100007d4be0212415ae3920fbd92c2547f5419ac8da07bb7e29488472a434a2", + "sourceCodeHash": "0xbeb2bc02cd40403b3a6d27344bb6a04637729934bf8cb8754e6b8058f4ee5230" + }, + { + "contractName": "L1Messenger", + "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", + "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", + "bytecodeHash": "0x0100028debc3f96ddf2c6630fb28ac7b4ae198ad453fdc08df2e81e6d2a4aa0b", + "sourceCodeHash": "0xb2839be528f2da61332fccec5268d966ca1aa3985839b6bab9b54e653aba5c72" + }, + { + "contractName": "L2EthToken", + "bytecodePath": "artifacts-zk/contracts-preprocessed/L2EthToken.sol/L2EthToken.json", + "sourceCodePath": "contracts-preprocessed/L2EthToken.sol", + "bytecodeHash": "0x01000101dbb3209311751d4f335ac6909943e19a1c3d26cdd27db01adb509db0", + "sourceCodeHash": "0x98d016a199cb47db6c5095950a186b91a43705f23aca5143cc258b6ef9a812ca" + }, + { + "contractName": "MsgValueSimulator", + "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", + "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", + "bytecodeHash": "0x01000063d13c3fdbd042669053befb649f89c1dd0de3d7a0542486e89b6a7f00", + "sourceCodeHash": "0x97678bbc9b6a6b1b0c1e8b2502b07da917a05f34eeb29bd0e2c0c2d0a93fe901" + }, + { + "contractName": "NonceHolder", + "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", + "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", + "bytecodeHash": "0x010000e52e563c15152eb655ea2d1b633c1409b61afa74065d05e93107a7e223", + "sourceCodeHash": "0x3dbb6b31b83253b962e88a937c8fd2ca1811b082f5e16695274edc08cf40e013" + }, + { + "contractName": "SystemContext", + "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", + "sourceCodePath": "contracts-preprocessed/SystemContext.sol", + "bytecodeHash": "0x01000181e472c23b9b5e9b971dec1971183ab06fb5932ea469ee207cc4a668da", + "sourceCodeHash": "0xcdefeee029d7bfaec6b8cfa136a88016c537420e5da0f0edbf126055ce1eb8ca" + }, + { + "contractName": "EventWriter", + "bytecodePath": "contracts-preprocessed/artifacts/EventWriter.yul.zbin", + "sourceCodePath": "contracts-preprocessed/EventWriter.yul", + "bytecodeHash": "0x0100001752ddb6f7d76adaf32594816c0bda5b9c17d6fd86e90a06acba2e4cb6", + "sourceCodeHash": "0x55cfee65f174350edfd690c949bc0a29458f25da11f1d5f90b57621567df1fc3" + }, + { + "contractName": "EcAdd", + "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcAdd.yul.zbin", + "sourceCodePath": "contracts-preprocessed/precompiles/EcAdd.yul", + "bytecodeHash": "0x0100008f337dc5cc92411071569be5cd4bfd755adf20021c8a0e316c4834c4ef", + "sourceCodeHash": "0x32645126b8765e4f7ced63c9508c70edc4ab734843d5f0f0f01d153c27206cee" + }, + { + "contractName": "EcMul", + "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcMul.yul.zbin", + "sourceCodePath": "contracts-preprocessed/precompiles/EcMul.yul", + "bytecodeHash": "0x010000d941fe2d54aa725915db7d63795e02ced38fa2709d736631e30792ccb2", + "sourceCodeHash": "0xdad8be6e926155a362ea05b132ba8b6c634e978a41f79bb6390b870e18049e45" + }, + { + "contractName": "Ecrecover", + "bytecodePath": "contracts-preprocessed/precompiles/artifacts/Ecrecover.yul.zbin", + "sourceCodePath": "contracts-preprocessed/precompiles/Ecrecover.yul", + "bytecodeHash": "0x0100001147fcb33fbc266df8067be8b51d68ad9362a6204de5a6b2279c613d12", + "sourceCodeHash": "0xe2334f04fa8003d448c7e6bfb345e644f2c851328aa5b49cb30acf45d6e0bbcf" + }, + { + "contractName": "Keccak256", + "bytecodePath": "contracts-preprocessed/precompiles/artifacts/Keccak256.yul.zbin", + "sourceCodePath": "contracts-preprocessed/precompiles/Keccak256.yul", + "bytecodeHash": "0x01000021e3954694ddb9479f31cabe797467b4ea3b92ab64fd81e9b5e53f1300", + "sourceCodeHash": "0x6415e127a4e07907fb87d0cbdf480fff8c70326c4f2f670af0cf3248862e4df4" + }, + { + "contractName": "SHA256", + "bytecodePath": "contracts-preprocessed/precompiles/artifacts/SHA256.yul.zbin", + "sourceCodePath": "contracts-preprocessed/precompiles/SHA256.yul", + "bytecodeHash": "0x010000179d3c90b59acbc8fbda5ba2389cc80dfa840840e5183d44ea3c9b0131", + "sourceCodeHash": "0x8f5a719394836111c850774e89ffb22ef825ff4d24d116ca750888be906f0109" + }, + { + "contractName": "bootloader_test", + "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", + "sourceCodePath": "bootloader/build/bootloader_test.yul", + "bytecodeHash": "0x01000341d30b181d174a0dfdd332bf3818c4ef043059c2bebea734606ae41564", + "sourceCodeHash": "0xe44fe857497c0c129708c7d0d87bbe676006419d77de4bc70ad6787d584ce26d" + }, + { + "contractName": "fee_estimate", + "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", + "sourceCodePath": "bootloader/build/fee_estimate.yul", + "bytecodeHash": "0x0100084d5ae9222debe8ebc5d0c06e81cda2d9df1a8befb62af0c858af05275d", + "sourceCodeHash": "0x787f56b8b813818187b2070307a76c2fc98058fb38c37d2763a623409764e9dc" + }, + { + "contractName": "gas_test", + "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", + "sourceCodePath": "bootloader/build/gas_test.yul", + "bytecodeHash": "0x0100081dc948944250554e665e20f506573eaf7056727e66fc6cce369b32ed18", + "sourceCodeHash": "0xa52ae3c448dc3b56e9ce0fde4702a37a8253e0c929f0c50de85fa26549e4198b" + }, + { + "contractName": "playground_batch", + "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", + "sourceCodePath": "bootloader/build/playground_batch.yul", + "bytecodeHash": "0x01000853f76c5247432bdaea15f65109ab3dda0b65af5573360f30843989f04b", + "sourceCodeHash": "0xf38e29b4dd0db36e56f528baee48f583f088cc23ce761fad7cc2d0088a5734ca" + }, + { + "contractName": "proved_batch", + "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", + "sourceCodePath": "bootloader/build/proved_batch.yul", + "bytecodeHash": "0x01000831ba7021800f5d9103772fcc7463ed7e764a2a3624cacca6b3826172d0", + "sourceCodeHash": "0xae37cb68cad70b56e8b4c3f987168625746950b4d7c77c39f7f506baa29fa91a" + } +] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul new file mode 100644 index 000000000..be00cf3c4 --- /dev/null +++ b/system-contracts/bootloader/bootloader.yul @@ -0,0 +1,3891 @@ +object "Bootloader" { + code { + } + object "Bootloader_deployed" { + code { + {{CODE_START_PLACEHOLDER}} + + //////////////////////////////////////////////////////////////////////////// + // Function Declarations + //////////////////////////////////////////////////////////////////////////// + + // While we definitely cannot control the gas price on L1, + // we need to check the operator does not provide any absurd numbers there + function MAX_ALLOWED_L1_GAS_PRICE() -> ret { + // 100k gwei + ret := 100000000000000 + } + + function MAX_ALLOWED_FAIR_L2_GAS_PRICE() -> ret { + // 10k gwei + ret := 10000000000000 + } + + /// @dev This method ensures that the prices provided by the operator + /// are not absurdly high + function validateOperatorProvidedPrices(l1GasPrice, fairL2GasPrice) { + if gt(l1GasPrice, MAX_ALLOWED_L1_GAS_PRICE()) { + assertionError("L1 gas price too high") + } + + if gt(fairL2GasPrice, MAX_ALLOWED_FAIR_L2_GAS_PRICE()) { + assertionError("L2 fair gas price too high") + } + } + + /// @dev Returns the baseFee for this batch based on the + /// L1 gas price and the fair L2 gas price. + function getBaseFee(l1GasPrice, fairL2GasPrice) -> baseFee, gasPricePerPubdata { + // By default, we want to provide the fair L2 gas price. + // That it means that the operator controls + // what the value of the baseFee will be. In the future, + // a better system, aided by EIP1559 should be added. + + let pubdataBytePriceETH := safeMul(l1GasPrice, L1_GAS_PER_PUBDATA_BYTE(), "aoa") + + baseFee := max( + fairL2GasPrice, + ceilDiv(pubdataBytePriceETH, MAX_L2_GAS_PER_PUBDATA()) + ) + gasPricePerPubdata := ceilDiv(pubdataBytePriceETH, baseFee) + } + + /// @dev It should be always possible to submit a transaction + /// that consumes such amount of public data. + function GUARANTEED_PUBDATA_PER_TX() -> ret { + ret := {{GUARANTEED_PUBDATA_BYTES}} + } + + /// @dev The maximal gasPerPubdata, which allows users to still be + /// able to send `GUARANTEED_PUBDATA_PER_TX` onchain. + function MAX_L2_GAS_PER_PUBDATA() -> ret { + ret := div(MAX_GAS_PER_TRANSACTION(), GUARANTEED_PUBDATA_PER_TX()) + } + + /// @dev The computational overhead for a batch. + /// It includes the combined price for 1 instance of all the circuits + /// (since they might be partially filled), the price for running + /// the common parts of the bootloader as well as general maintainance of the system. + function BATCH_OVERHEAD_L2_GAS() -> ret { + ret := {{BATCH_OVERHEAD_L2_GAS}} + } + + /// @dev The overhead for the interaction with L1. + /// It should cover proof verification as well as other minor + /// overheads for committing/executing a transaction in a batch. + function BATCH_OVERHEAD_L1_GAS() -> ret { + ret := {{BATCH_OVERHEAD_L1_GAS}} + } + + /// @dev The maximal number of gas available to the transaction + function MAX_GAS_PER_TRANSACTION() -> ret { + ret := {{MAX_GAS_PER_TRANSACTION}} + } + + /// @dev The number of L1 gas needed to be spent for + /// L1 byte. While a single pubdata byte costs `16` gas, + /// we demand at least 17 to cover up for the costs of additional + /// hashing of it, etc. + function L1_GAS_PER_PUBDATA_BYTE() -> ret { + ret := 17 + } + + /// @dev The size of the bootloader memory that is to spent by the transaction's + /// encodings. + function BOOTLOADER_MEMORY_FOR_TXS() -> ret { + ret := {{BOOTLOADER_MEMORY_FOR_TXS}} + } + + /// @dev Whether the batch is allowed to accept transactions with + /// gasPerPubdataByteLimit = 0. On mainnet, this is forbidden for safety reasons. + function FORBID_ZERO_GAS_PER_PUBDATA() -> ret { + ret := {{FORBID_ZERO_GAS_PER_PUBDATA}} + } + + /// @dev The maximum number of transactions per L1 batch. + function MAX_TRANSACTIONS_IN_BATCH() -> ret { + ret := {{MAX_TRANSACTIONS_IN_BATCH}} + } + + /// @dev The slot from which the scratch space starts. + /// Scatch space is used for various temporary values + function SCRATCH_SPACE_BEGIN_SLOT() -> ret { + ret := 8 + } + + /// @dev The byte from which the scratch space starts. + /// Scratch space is used for various temporary values + function SCRATCH_SPACE_BEGIN_BYTE() -> ret { + ret := mul(SCRATCH_SPACE_BEGIN_SLOT(), 32) + } + + /// @dev The first 32 slots are reserved for event emitting for the + /// debugging purposes + function SCRATCH_SPACE_SLOTS() -> ret { + ret := 32 + } + + /// @dev Slots reserved for saving the paymaster context + /// @dev The paymasters are allowed to consume at most + /// 32 slots (1024 bytes) for their context. + /// The 33 slots are required since the first one stores the length of the calldata. + function PAYMASTER_CONTEXT_SLOTS() -> ret { + ret := 33 + } + + /// @dev Bytes reserved for saving the paymaster context + function PAYMASTER_CONTEXT_BYTES() -> ret { + ret := mul(PAYMASTER_CONTEXT_SLOTS(), 32) + } + + /// @dev Slot from which the paymaster context starts + function PAYMASTER_CONTEXT_BEGIN_SLOT() -> ret { + ret := add(SCRATCH_SPACE_BEGIN_SLOT(), SCRATCH_SPACE_SLOTS()) + } + + /// @dev The byte from which the paymaster context starts + function PAYMASTER_CONTEXT_BEGIN_BYTE() -> ret { + ret := mul(PAYMASTER_CONTEXT_BEGIN_SLOT(), 32) + } + + /// @dev Each tx must have at least this amount of unused bytes before them to be able to + /// encode the postOp operation correctly. + function MAX_POSTOP_SLOTS() -> ret { + // Before the actual transaction encoding, the postOp contains 6 slots: + // 1. Context offset + // 2. Transaction offset + // 3. Transaction hash + // 4. Suggested signed hash + // 5. Transaction result + // 6. Maximum refunded gas + // And one more slot for the padding selector + ret := add(PAYMASTER_CONTEXT_SLOTS(), 7) + } + + /// @dev Slots needed to store the canonical and signed hash for the current L2 transaction. + function CURRENT_L2_TX_HASHES_RESERVED_SLOTS() -> ret { + ret := 2 + } + + /// @dev Slot from which storing of the current canonical and signed hashes begins + function CURRENT_L2_TX_HASHES_BEGIN_SLOT() -> ret { + ret := add(PAYMASTER_CONTEXT_BEGIN_SLOT(), PAYMASTER_CONTEXT_SLOTS()) + } + + /// @dev The byte from which storing of the current canonical and signed hashes begins + function CURRENT_L2_TX_HASHES_BEGIN_BYTE() -> ret { + ret := mul(CURRENT_L2_TX_HASHES_BEGIN_SLOT(), 32) + } + + /// @dev The maximum number of new factory deps that are allowed in a transaction + function MAX_NEW_FACTORY_DEPS() -> ret { + ret := 32 + } + + /// @dev Besides the factory deps themselves, we also need another 4 slots for: + /// selector, marker of whether the user should pay for the pubdata, + /// the offset for the encoding of the array as well as the length of the array. + function NEW_FACTORY_DEPS_RESERVED_SLOTS() -> ret { + ret := add(MAX_NEW_FACTORY_DEPS(), 4) + } + + /// @dev The slot starting from which the factory dependencies are stored + function NEW_FACTORY_DEPS_BEGIN_SLOT() -> ret { + ret := add(CURRENT_L2_TX_HASHES_BEGIN_SLOT(), CURRENT_L2_TX_HASHES_RESERVED_SLOTS()) + } + + /// @dev The byte starting from which the factory dependencies are stored + function NEW_FACTORY_DEPS_BEGIN_BYTE() -> ret { + ret := mul(NEW_FACTORY_DEPS_BEGIN_SLOT(), 32) + } + + /// @dev The slot starting from which the refunds provided by the operator are stored + function TX_OPERATOR_REFUND_BEGIN_SLOT() -> ret { + ret := add(NEW_FACTORY_DEPS_BEGIN_SLOT(), NEW_FACTORY_DEPS_RESERVED_SLOTS()) + } + + /// @dev The byte starting from which the refunds provided by the operator are stored + function TX_OPERATOR_REFUND_BEGIN_BYTE() -> ret { + ret := mul(TX_OPERATOR_REFUND_BEGIN_SLOT(), 32) + } + + /// @dev The number of slots dedicated for the refunds for the transactions. + /// It is equal to the number of transactions in the batch. + function TX_OPERATOR_REFUNDS_SLOTS() -> ret { + ret := MAX_TRANSACTIONS_IN_BATCH() + } + + /// @dev The slot starting from which the overheads proposed by the operator will be stored + function TX_SUGGESTED_OVERHEAD_BEGIN_SLOT() -> ret { + ret := add(TX_OPERATOR_REFUND_BEGIN_SLOT(), TX_OPERATOR_REFUNDS_SLOTS()) + } + + /// @dev The byte starting from which the overheads proposed by the operator will be stored + function TX_SUGGESTED_OVERHEAD_BEGIN_BYTE() -> ret { + ret := mul(TX_SUGGESTED_OVERHEAD_BEGIN_SLOT(), 32) + } + + /// @dev The number of slots dedicated for the overheads for the transactions. + /// It is equal to the number of transactions in the batch. + function TX_SUGGESTED_OVERHEAD_SLOTS() -> ret { + ret := MAX_TRANSACTIONS_IN_BATCH() + } + + /// @dev The slot starting from which the maximum number of gas that the operator "trusts" + /// the transaction to use for its execution is stored. Sometimes, the operator may know that + /// a certain transaction can be allowed more gas that what the protocol-level worst-case allows. + function TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_SLOT() -> ret { + ret := add(TX_SUGGESTED_OVERHEAD_BEGIN_SLOT(), TX_SUGGESTED_OVERHEAD_SLOTS()) + } + + /// @dev byte starting from which the maximum number of gas that the operator "trusts" + /// the transaction to use for its execution is stored. + function TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_BYTE() -> ret { + ret := mul(TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_SLOT(), 32) + } + + /// @dev The number of slots dedicated for the trusted gas limits for the transactions. + /// It is equal to the number of transactions in the batch. + function TX_OPERATOR_TRUSTED_GAS_LIMIT_SLOTS() -> ret { + ret := MAX_TRANSACTIONS_IN_BATCH() + } + + /// @dev The slot starting from the L2 block information for transactions is stored. + function TX_OPERATOR_L2_BLOCK_INFO_BEGIN_SLOT() -> ret { + ret := add(TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_SLOT(), TX_OPERATOR_TRUSTED_GAS_LIMIT_SLOTS()) + } + + /// @dev The byte starting from which the L2 block information for transactions is stored. + function TX_OPERATOR_L2_BLOCK_INFO_BEGIN_BYTE() -> ret { + ret := mul(TX_OPERATOR_L2_BLOCK_INFO_BEGIN_SLOT(), 32) + } + + /// @dev The size of each of the L2 block information. Each L2 block information contains four fields: + /// - number of the block + /// - timestamp of the block + /// - hash of the previous block + /// - the maximal number of virtual blocks to create + function TX_OPERATOR_L2_BLOCK_INFO_SLOT_SIZE() -> ret { + ret := 4 + } + + /// @dev The size of each of the L2 block information in bytes. + function TX_OPERATOR_L2_BLOCK_INFO_SIZE_BYTES() -> ret { + ret := mul(TX_OPERATOR_L2_BLOCK_INFO_SLOT_SIZE(), 32) + } + + /// @dev The number of slots dedicated for the L2 block information for the transactions. + /// Note, that an additional slot is required for the fictive L2 block at the end of the batch. + /// For technical reasons inside the sequencer implementation, + /// each batch ends with a fictive block with no transactions. + function TX_OPERATOR_L2_BLOCK_INFO_SLOTS() -> ret { + ret := mul(add(MAX_TRANSACTIONS_IN_BATCH(), 1), TX_OPERATOR_L2_BLOCK_INFO_SLOT_SIZE()) + } + + /// @dev The slot starting from which the compressed bytecodes are located in the bootloader's memory. + /// Each compressed bytecode is provided in the following format: + /// - 32 byte formatted bytecode hash + /// - 32 byte of zero (it will be replaced within the code with left-padded selector of the `publishCompressedBytecode`). + /// - ABI-encoding of the parameters of the `publishCompressedBytecode` method. + /// + /// At the slot `TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_SLOT()` the pointer to the currently processed compressed bytecode + /// is stored, i.e. this pointer will be increased once the current bytecode which the pointer points to is published. + /// At the start of the bootloader, the value stored at the `TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_SLOT` is equal to + /// `TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_SLOT + 32`, where the hash of the first compressed bytecode to publish should be stored. + function COMPRESSED_BYTECODES_BEGIN_SLOT() -> ret { + ret := add(TX_OPERATOR_L2_BLOCK_INFO_BEGIN_SLOT(), TX_OPERATOR_L2_BLOCK_INFO_SLOTS()) + } + + /// @dev The byte starting from which the compressed bytecodes are located in the bootloader's memory. + function COMPRESSED_BYTECODES_BEGIN_BYTE() -> ret { + ret := mul(COMPRESSED_BYTECODES_BEGIN_SLOT(), 32) + } + + /// @dev The number of slots dedicated to the compressed bytecodes. + function COMPRESSED_BYTECODES_SLOTS() -> ret { + ret := {{COMPRESSED_BYTECODES_SLOTS}} + } + + /// @dev The slot right after the last slot of the compressed bytecodes memory area. + function COMPRESSED_BYTECODES_END_SLOT() -> ret { + ret := add(COMPRESSED_BYTECODES_BEGIN_SLOT(), COMPRESSED_BYTECODES_SLOTS()) + } + + /// @dev The first byte in memory right after the compressed bytecodes memory area. + function COMPRESSED_BYTECODES_END_BYTE() -> ret { + ret := mul(COMPRESSED_BYTECODES_END_SLOT(), 32) + } + + /// @dev Slots needed to store priority txs L1 data (`chainedPriorityTxsHash` and `numberOfLayer1Txs`). + function PRIORITY_TXS_L1_DATA_RESERVED_SLOTS() -> ret { + ret := 2 + } + + /// @dev Slot from which storing of the priority txs L1 data begins. + function PRIORITY_TXS_L1_DATA_BEGIN_SLOT() -> ret { + ret := add(COMPRESSED_BYTECODES_BEGIN_SLOT(), COMPRESSED_BYTECODES_SLOTS()) + } + + /// @dev The byte from which storing of the priority txs L1 data begins. + function PRIORITY_TXS_L1_DATA_BEGIN_BYTE() -> ret { + ret := mul(PRIORITY_TXS_L1_DATA_BEGIN_SLOT(), 32) + } + + /// @dev Slot from which storing of the L1 Messenger pubdata begins. + function OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_BEGIN_SLOT() -> ret { + ret := add(PRIORITY_TXS_L1_DATA_BEGIN_SLOT(), PRIORITY_TXS_L1_DATA_RESERVED_SLOTS()) + } + + /// @dev The byte storing of the L1 Messenger pubdata begins. + function OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_BEGIN_BYTE() -> ret { + ret := mul(OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_BEGIN_SLOT(), 32) + } + + /// @dev Slots needed to store L1 Messenger pubdata. + /// @dev Note that are many more these than the maximal pubdata in batch, since + /// it needs to also accomodate uncompressed state diffs that are required for the state diff + /// compression verification. + function OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS() -> ret { + ret := {{OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS}} + } + + /// @dev The slot right after the last slot of the L1 Messenger pubdata memory area. + function OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_END_SLOT() -> ret { + ret := add(OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_BEGIN_SLOT(), OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS()) + } + + /// @dev The slot from which the bootloader transactions' descriptions begin + function TX_DESCRIPTION_BEGIN_SLOT() -> ret { + ret := OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_END_SLOT() + } + + /// @dev The byte from which the bootloader transactions' descriptions begin + function TX_DESCRIPTION_BEGIN_BYTE() -> ret { + ret := mul(TX_DESCRIPTION_BEGIN_SLOT(), 32) + } + + // Each tx description has the following structure + // + // struct BootloaderTxDescription { + // uint256 txMeta; + // uint256 txDataOffset; + // } + // + // `txMeta` contains flags to manipulate the transaction execution flow. + // For playground batches: + // It can have the following information (0 byte is LSB and 31 byte is MSB): + // 0 byte: `execute`, bool. Denotes whether transaction should be executed by the bootloader. + // 31 byte: server-side tx execution mode + // For proved batches: + // It can simply denotes whether to execute the transaction (0 to stop executing the batch, 1 to continue) + // + // Each such encoded struct consumes 2 words + function TX_DESCRIPTION_SIZE() -> ret { + ret := 64 + } + + /// @dev The byte right after the basic description of bootloader transactions + function TXS_IN_BATCH_LAST_PTR() -> ret { + ret := add(TX_DESCRIPTION_BEGIN_BYTE(), mul(MAX_TRANSACTIONS_IN_BATCH(), TX_DESCRIPTION_SIZE())) + } + + /// @dev The memory page consists of 2^19 VM words. + /// Each execution result is a single boolean, but + /// for the sake of simplicity we will spend 32 bytes on each + /// of those for now. + function MAX_MEM_SIZE() -> ret { + ret := 0x1000000 // 2^24 bytes + } + + function L1_TX_INTRINSIC_L2_GAS() -> ret { + ret := {{L1_TX_INTRINSIC_L2_GAS}} + } + + function L1_TX_INTRINSIC_PUBDATA() -> ret { + ret := {{L1_TX_INTRINSIC_PUBDATA}} + } + + function L2_TX_INTRINSIC_GAS() -> ret { + ret := {{L2_TX_INTRINSIC_GAS}} + } + + function L2_TX_INTRINSIC_PUBDATA() -> ret { + ret := {{L2_TX_INTRINSIC_PUBDATA}} + } + + /// @dev The byte from which the pointers on the result of transactions are stored + function RESULT_START_PTR() -> ret { + ret := sub(MAX_MEM_SIZE(), mul(MAX_TRANSACTIONS_IN_BATCH(), 32)) + } + + /// @dev The pointer writing to which invokes the VM hooks + function VM_HOOK_PTR() -> ret { + ret := sub(RESULT_START_PTR(), 32) + } + + /// @dev The maximum number the VM hooks may accept + function VM_HOOK_PARAMS() -> ret { + ret := 2 + } + + /// @dev The offset starting from which the parameters for VM hooks are located + function VM_HOOK_PARAMS_OFFSET() -> ret { + ret := sub(VM_HOOK_PTR(), mul(VM_HOOK_PARAMS(), 32)) + } + + function LAST_FREE_SLOT() -> ret { + // The slot right before the vm hooks is the last slot that + // can be used for transaction's descriptions + ret := sub(VM_HOOK_PARAMS_OFFSET(), 32) + } + + /// @dev The formal address of the bootloader + function BOOTLOADER_FORMAL_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008001 + } + + function MAX_SYSTEM_CONTRACT_ADDR() -> ret { + ret := 0x000000000000000000000000000000000000ffff + } + + function ACCOUNT_CODE_STORAGE_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008002 + } + + function NONCE_HOLDER_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008003 + } + + function KNOWN_CODES_CONTRACT_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008004 + } + + function CONTRACT_DEPLOYER_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008006 + } + + function FORCE_DEPLOYER() -> ret { + ret := 0x0000000000000000000000000000000000008007 + } + + function MSG_VALUE_SIMULATOR_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008009 + } + + function ETH_L2_TOKEN_ADDR() -> ret { + ret := 0x000000000000000000000000000000000000800a + } + + function SYSTEM_CONTEXT_ADDR() -> ret { + ret := 0x000000000000000000000000000000000000800b + } + + function BOOTLOADER_UTILITIES() -> ret { + ret := 0x000000000000000000000000000000000000800c + } + + function BYTECODE_COMPRESSOR_ADDR() -> ret { + ret := 0x000000000000000000000000000000000000800e + } + + function L1_MESSENGER_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008008 + } + + /// @dev The minimal allowed distance in bytes between the pointer to the compressed data + /// and the end of the area dedicated for the compressed bytecodes. + /// In fact, only distance of 192 should be sufficient: there it would be possible to insert + /// the hash of the bytecode, the 32 bytes buffer for selector and 2 offsets of the calldata, + /// but we keep it at 512 just in case. + function MIN_ALLOWED_OFFSET_FOR_COMPRESSED_BYTES_POINTER() -> ret { + ret := 512 + } + + /// @dev Whether the bootloader should enforce that accounts have returned the correct + /// magic value for signature. This value is enforced to be "true" on the main proved batch, but + /// we need the ability to ignore invalid signature results during fee estimation, + /// where the signature for the transaction is usually not known beforehand. + function SHOULD_ENSURE_CORRECT_RETURNED_MAGIC() -> ret { + ret := {{ENSURE_RETURNED_MAGIC}} + } + + /// @notice The type of the transaction used for system upgrades. + function UPGRADE_TRANSACTION_TX_TYPE() -> ret { + ret := 254 + } + + /// @notice The type of every non-upgrade transaction that comes from L1. + function L1_TX_TYPE() -> ret { + ret := 255 + } + + /// @dev The overhead in gas that will be used when checking whether the context has enough gas, i.e. + /// when checking for X gas, the context should have at least X+CHECK_ENOUGH_GAS_OVERHEAD() gas. + function CHECK_ENOUGH_GAS_OVERHEAD() -> ret { + ret := 1000000 + } + + /// @dev Ceil division of integers + function ceilDiv(x, y) -> ret { + switch or(eq(x, 0), eq(y, 0)) + case 0 { + // (x + y - 1) / y can overflow on addition, so we distribute. + ret := add(div(sub(x, 1), y), 1) + } + default { + ret := 0 + } + } + + /// @dev Calculates the length of a given number of bytes rounded up to the nearest multiple of 32. + function lengthRoundedByWords(len) -> ret { + let neededWords := div(add(len, 31), 32) + ret := safeMul(neededWords, 32, "xv") + } + + /// @dev Function responsible for processing the transaction + /// @param txDataOffset The offset to the ABI-encoding of the structure + /// @param resultPtr The pointer at which the result of the transaction's execution should be stored + /// @param transactionIndex The index of the transaction in the batch + /// @param isETHCall Whether the call is an ethCall. + /// @param gasPerPubdata The number of L2 gas to charge users for each byte of pubdata + /// On proved batch this value should always be zero + function processTx( + txDataOffset, + resultPtr, + transactionIndex, + isETHCall, + gasPerPubdata + ) { + // We set the L2 block info for this particular transaction + setL2Block(transactionIndex) + + let innerTxDataOffset := add(txDataOffset, 32) + + // By default we assume that the transaction has failed. + mstore(resultPtr, 0) + + let userProvidedPubdataPrice := getGasPerPubdataByteLimit(innerTxDataOffset) + debugLog("userProvidedPubdataPrice:", userProvidedPubdataPrice) + + debugLog("gasPerPubdata:", gasPerPubdata) + + switch getTxType(innerTxDataOffset) + case 254 { + // This is an upgrade transaction. + // Protocol upgrade transactions are processed totally in the same manner as the normal L1->L2 transactions, + // the only difference are: + // - They must be the first one in the batch + // - They have a different type to prevent tx hash collisions and preserve the expectation that the + // L1->L2 transactions have priorityTxId inside them. + if transactionIndex { + assertionError("Protocol upgrade tx not first") + } + + // This is to be called in the event that the L1 Transaction is a protocol upgrade txn. + // Since this is upgrade transactions, we are okay that the gasUsed by the transaction will + // not cover this additional hash computation + let canonicalL1TxHash := getCanonicalL1TxHash(txDataOffset) + sendToL1Native(true, protocolUpgradeTxHashKey(), canonicalL1TxHash) + + processL1Tx(txDataOffset, resultPtr, transactionIndex, userProvidedPubdataPrice, false) + } + case 255 { + // This is an L1->L2 transaction. + processL1Tx(txDataOffset, resultPtr, transactionIndex, userProvidedPubdataPrice, true) + } + default { + // The user has not agreed to this pubdata price + if lt(userProvidedPubdataPrice, gasPerPubdata) { + revertWithReason(UNACCEPTABLE_GAS_PRICE_ERR_CODE(), 0) + } + + setPricePerPubdataByte(gasPerPubdata) + + + processL2Tx(txDataOffset, resultPtr, transactionIndex, gasPerPubdata) + + + + switch isETHCall + case 1 { + let gasLimit := getGasLimit(innerTxDataOffset) + let nearCallAbi := getNearCallABI(gasLimit) + checkEnoughGas(gasLimit) + + if iszero(gasLimit) { + // If success is 0, we need to revert + revertWithReason( + ETH_CALL_ERR_CODE(), + 0 + ) + } + + ZKSYNC_NEAR_CALL_ethCall( + nearCallAbi, + txDataOffset, + resultPtr + ) + } + default { + processL2Tx(txDataOffset, resultPtr, transactionIndex, gasPerPubdata) + } + + } + } + + /// @dev Checks whether the code hash of the system context contract is correct and updates it if needed. + /// @dev The L1 contracts expect all the system logs to be present in the first boojum upgrade batch already. + /// However, the old system context did not send the same system logs. Usually we upgrade system context + /// via an upgrade transaction, but in this case the transaction won't be even processed, because of failure to create an L2 block. + function upgradeSystemContextIfNeeded() { + let expectedCodeHash := {{SYSTEM_CONTEXT_EXPECTED_CODE_HASH}} + + let actualCodeHash := extcodehash(SYSTEM_CONTEXT_ADDR()) + if iszero(eq(expectedCodeHash, actualCodeHash)) { + // Preparing the calldata to upgrade the SystemContext contract + {{UPGRADE_SYSTEM_CONTEXT_CALLDATA}} + + // We'll use a mimicCall to simulate the correct sender. + let success := mimicCallOnlyResult( + CONTRACT_DEPLOYER_ADDR(), + FORCE_DEPLOYER(), + 0, + 0, + 0, + 0, + 0, + 0 + ) + + if iszero(success) { + assertionError("system context upgrade fail") + } + } + } + + /// @dev Calculates the canonical hash of the L1->L2 transaction that will be + /// sent to L1 as a message to the L1 contract that a certain operation has been processed. + function getCanonicalL1TxHash(txDataOffset) -> ret { + // Putting the correct value at the `txDataOffset` just in case, since + // the correctness of this value is not part of the system invariants. + // Note, that the correct ABI encoding of the Transaction structure starts with 0x20 + mstore(txDataOffset, 32) + + let innerTxDataOffset := add(txDataOffset, 32) + let dataLength := safeAdd(32, getDataLength(innerTxDataOffset), "qev") + + debugLog("HASH_OFFSET", innerTxDataOffset) + debugLog("DATA_LENGTH", dataLength) + + ret := keccak256(txDataOffset, dataLength) + } + + /// @dev The purpose of this function is to make sure that the operator + /// gets paid for the transaction. Note, that the beneficiary of the payment is + /// bootloader. + /// The operator will be paid at the end of the batch. + function ensurePayment(txDataOffset, gasPrice) { + // Skipping the first 0x20 byte in the encoding of the transaction. + let innerTxDataOffset := add(txDataOffset, 32) + let from := getFrom(innerTxDataOffset) + let requiredETH := safeMul(getGasLimit(innerTxDataOffset), gasPrice, "lal") + + let bootloaderBalanceETH := balance(BOOTLOADER_FORMAL_ADDR()) + let paymaster := getPaymaster(innerTxDataOffset) + + let payer := 0 + + switch paymaster + case 0 { + payer := from + + // There is no paymaster, the user should pay for the execution. + // Calling for the `payForTransaction` method of the account. + setHook(VM_HOOK_ACCOUNT_VALIDATION_ENTERED()) + let res := accountPayForTx(from, txDataOffset) + setHook(VM_HOOK_NO_VALIDATION_ENTERED()) + + + if iszero(res) { + revertWithReason( + PAY_FOR_TX_FAILED_ERR_CODE(), + 1 + ) + } + } + default { + // There is some paymaster present. + payer := paymaster + + // Firstly, the `prepareForPaymaster` method of the user's account is called. + setHook(VM_HOOK_ACCOUNT_VALIDATION_ENTERED()) + let userPrePaymasterResult := accountPrePaymaster(from, txDataOffset) + setHook(VM_HOOK_NO_VALIDATION_ENTERED()) + + if iszero(userPrePaymasterResult) { + revertWithReason( + PRE_PAYMASTER_PREPARATION_FAILED_ERR_CODE(), + 1 + ) + } + + // Then, the paymaster is called. The paymaster should pay us in this method. + setHook(VM_HOOK_PAYMASTER_VALIDATION_ENTERED()) + let paymasterPaymentSuccess := validateAndPayForPaymasterTransaction(paymaster, txDataOffset) + if iszero(paymasterPaymentSuccess) { + revertWithReason( + PAYMASTER_VALIDATION_FAILED_ERR_CODE(), + 1 + ) + } + + storePaymasterContextAndCheckMagic() + setHook(VM_HOOK_NO_VALIDATION_ENTERED()) + } + + let bootloaderReceivedFunds := safeSub(balance(BOOTLOADER_FORMAL_ADDR()), bootloaderBalanceETH, "qsx") + + // If the amount of funds provided to the bootloader is less than the minimum required one + // then this transaction should be rejected. + if lt(bootloaderReceivedFunds, requiredETH) { + revertWithReason( + FAILED_TO_CHARGE_FEE_ERR_CODE(), + 0 + ) + } + + let excessiveFunds := safeSub(bootloaderReceivedFunds, requiredETH, "llm") + + if gt(excessiveFunds, 0) { + // Returning back the excessive funds taken. + directETHTransfer(excessiveFunds, payer) + } + } + + /// @notice Mints ether to the recipient + /// @param to -- the address of the recipient + /// @param amount -- the amount of ETH to mint + /// @param useNearCallPanic -- whether to use nearCallPanic in case of + /// the transaction failing to execute. It is desirable in cases + /// where we want to allow the method fail without reverting the entire bootloader + function mintEther(to, amount, useNearCallPanic) { + mstore(0, {{RIGHT_PADDED_MINT_ETHER_SELECTOR}}) + mstore(4, to) + mstore(36, amount) + let success := call( + gas(), + ETH_L2_TOKEN_ADDR(), + 0, + 0, + 68, + 0, + 0 + ) + if iszero(success) { + switch useNearCallPanic + case 0 { + revertWithReason( + MINT_ETHER_FAILED_ERR_CODE(), + 0 + ) + } + default { + nearCallPanic() + } + } + } + + /// @dev Saves the paymaster context and checks that the paymaster has returned the correct + /// magic value. + /// @dev IMPORTANT: this method should be called right after + /// the validateAndPayForPaymasterTransaction method to keep the `returndata` from that transaction + function storePaymasterContextAndCheckMagic() { + // The paymaster validation step should return context of type "bytes context" + // This means that the returndata is encoded the following way: + // 0x20 || context_len || context_bytes... + let returnlen := returndatasize() + // The minimal allowed returndatasize is 64: magicValue || offset + if lt(returnlen, 64) { + revertWithReason( + PAYMASTER_RETURNED_INVALID_CONTEXT(), + 0 + ) + } + + // Note that it is important to copy the magic even though it is not needed if the + // `SHOULD_ENSURE_CORRECT_RETURNED_MAGIC` is false. It is never false in production + // but it is so in fee estimation and we want to preserve as many operations as + // in the original operation. + { + returndatacopy(0, 0, 32) + let magic := mload(0) + + let isMagicCorrect := eq(magic, {{SUCCESSFUL_PAYMASTER_VALIDATION_MAGIC_VALUE}}) + + if and(iszero(isMagicCorrect), SHOULD_ENSURE_CORRECT_RETURNED_MAGIC()) { + revertWithReason( + PAYMASTER_RETURNED_INVALID_MAGIC_ERR_CODE(), + 0 + ) + } + } + + returndatacopy(0, 32, 32) + let returnedContextOffset := mload(0) + + // Ensuring that the returned offset is not greater than the returndata length + // Note, that we cannot use addition here to prevent an overflow + if gt(returnedContextOffset, returnlen) { + revertWithReason( + PAYMASTER_RETURNED_INVALID_CONTEXT(), + 0 + ) + } + + // Can not read the returned length. + // It is safe to add here due to the previous check. + if gt(add(returnedContextOffset, 32), returnlen) { + revertWithReason( + PAYMASTER_RETURNED_INVALID_CONTEXT(), + 0 + ) + } + + // Reading the length of the context + returndatacopy(0, returnedContextOffset, 32) + let returnedContextLen := mload(0) + + // Ensuring that returnedContextLen is not greater than the length of the paymaster context + // Note, that this check at the same time prevents an overflow in the future operations with returnedContextLen + if gt(returnedContextLen, PAYMASTER_CONTEXT_BYTES()) { + revertWithReason( + PAYMASTER_RETURNED_CONTEXT_IS_TOO_LONG(), + 0 + ) + } + + let roundedContextLen := lengthRoundedByWords(returnedContextLen) + + // The returned context's size should not exceed the maximum length + if gt(add(roundedContextLen, 32), PAYMASTER_CONTEXT_BYTES()) { + revertWithReason( + PAYMASTER_RETURNED_CONTEXT_IS_TOO_LONG(), + 0 + ) + } + + if gt(add(returnedContextOffset, add(32, returnedContextLen)), returnlen) { + revertWithReason( + PAYMASTER_RETURNED_INVALID_CONTEXT(), + 0 + ) + } + + returndatacopy(PAYMASTER_CONTEXT_BEGIN_BYTE(), returnedContextOffset, add(32, returnedContextLen)) + } + + /// @dev The function responsible for processing L1->L2 transactions. + /// @param txDataOffset The offset to the transaction's information + /// @param resultPtr The pointer at which the result of the execution of this transaction + /// @param transactionIndex The index of the transaction + /// @param gasPerPubdata The price per pubdata to be used + /// @param isPriorityOp Whether the transaction is a priority one + /// should be stored. + function processL1Tx( + txDataOffset, + resultPtr, + transactionIndex, + gasPerPubdata, + isPriorityOp + ) { + // For L1->L2 transactions we always use the pubdata price provided by the transaction. + // This is needed to ensure DDoS protection. All the excess expenditure + // will be refunded to the user. + setPricePerPubdataByte(gasPerPubdata) + + // Skipping the first formal 0x20 byte + let innerTxDataOffset := add(txDataOffset, 32) + + let gasLimitForTx, reservedGas := getGasLimitForTx( + innerTxDataOffset, + transactionIndex, + gasPerPubdata, + L1_TX_INTRINSIC_L2_GAS(), + L1_TX_INTRINSIC_PUBDATA() + ) + + let gasUsedOnPreparation := 0 + let canonicalL1TxHash := 0 + + canonicalL1TxHash, gasUsedOnPreparation := l1TxPreparation(txDataOffset) + + let refundGas := 0 + let success := 0 + + // The invariant that the user deposited more than the value needed + // for the transaction must be enforced on L1, but we double check it here + let gasLimit := getGasLimit(innerTxDataOffset) + + // Note, that for now the property of block.base <= tx.maxFeePerGas does not work + // for L1->L2 transactions. For now, these transactions are processed with the same gasPrice + // they were provided on L1. In the future, we may apply a new logic for it. + let gasPrice := getMaxFeePerGas(innerTxDataOffset) + let txInternalCost := safeMul(gasPrice, gasLimit, "poa") + let value := getValue(innerTxDataOffset) + if lt(getReserved0(innerTxDataOffset), safeAdd(value, txInternalCost, "ol")) { + assertionError("deposited eth too low") + } + + if gt(gasLimitForTx, gasUsedOnPreparation) { + let potentialRefund := 0 + + potentialRefund, success := getExecuteL1TxAndGetRefund(txDataOffset, sub(gasLimitForTx, gasUsedOnPreparation)) + + // Asking the operator for refund + askOperatorForRefund(potentialRefund) + + // In case the operator provided smaller refund than the one calculated + // by the bootloader, we return the refund calculated by the bootloader. + refundGas := max(getOperatorRefundForTx(transactionIndex), safeAdd(potentialRefund, reservedGas, "iop")) + } + + if gt(refundGas, gasLimit) { + assertionError("L1: refundGas > gasLimit") + } + + let payToOperator := safeMul(gasPrice, safeSub(gasLimit, refundGas, "lpah"), "mnk") + + // Note, that for now, the L1->L2 transactions are free, i.e. the gasPrice + // for such transactions is always zero, so the `refundGas` is not used anywhere + // except for notifications for the operator for API purposes. + notifyAboutRefund(refundGas) + + // Paying the fee to the operator + mintEther(BOOTLOADER_FORMAL_ADDR(), payToOperator, false) + + let toRefundRecipient + switch success + case 0 { + if iszero(isPriorityOp) { + // Upgrade transactions must always succeed + assertionError("Upgrade tx failed") + } + + // If the transaction reverts, then minting the msg.value to the user has been reverted + // as well, so we can simply mint everything that the user has deposited to + // the refund recipient + toRefundRecipient := safeSub(getReserved0(innerTxDataOffset), payToOperator, "vji") + } + default { + // If the transaction succeeds, then it is assumed that msg.value was transferred correctly. However, the remaining + // ETH deposited will be given to the refund recipient. + + toRefundRecipient := safeSub(getReserved0(innerTxDataOffset), safeAdd(getValue(innerTxDataOffset), payToOperator, "kpa"), "ysl") + } + + if gt(toRefundRecipient, 0) { + let refundRecipient := getReserved1(innerTxDataOffset) + // Zero out the first 12 bytes to be sure that refundRecipient is address. + // In case of an issue in L1 contracts, we still will be able to process tx. + refundRecipient := and(refundRecipient, sub(shl(160, 1), 1)) + mintEther(refundRecipient, toRefundRecipient, false) + } + + mstore(resultPtr, success) + + debugLog("Send message to L1", success) + + // Sending the L2->L1 log so users will be able to prove transaction execution result on L1. + sendL2LogUsingL1Messenger(true, canonicalL1TxHash, success) + + if isPriorityOp { + // Update priority txs L1 data + mstore(0, mload(PRIORITY_TXS_L1_DATA_BEGIN_BYTE())) + mstore(32, canonicalL1TxHash) + mstore(PRIORITY_TXS_L1_DATA_BEGIN_BYTE(), keccak256(0, 64)) + mstore(add(PRIORITY_TXS_L1_DATA_BEGIN_BYTE(), 32), add(mload(add(PRIORITY_TXS_L1_DATA_BEGIN_BYTE(), 32)), 1)) + } + } + + function getExecuteL1TxAndGetRefund(txDataOffset, gasForExecution) -> potentialRefund, success { + debugLog("gasForExecution", gasForExecution) + + let callAbi := getNearCallABI(gasForExecution) + debugLog("callAbi", callAbi) + + checkEnoughGas(gasForExecution) + + let gasBeforeExecution := gas() + success := ZKSYNC_NEAR_CALL_executeL1Tx( + callAbi, + txDataOffset + ) + notifyExecutionResult(success) + let gasSpentOnExecution := sub(gasBeforeExecution, gas()) + + potentialRefund := sub(gasForExecution, gasSpentOnExecution) + if gt(gasSpentOnExecution, gasForExecution) { + potentialRefund := 0 + } + } + + /// @dev The function responsible for doing all the pre-execution operations for L1->L2 transactions. + /// @param txDataOffset The offset to the transaction's information + /// @return canonicalL1TxHash The hash of processed L1->L2 transaction + /// @return gasUsedOnPreparation The number of L2 gas used in the preparation stage + function l1TxPreparation(txDataOffset) -> canonicalL1TxHash, gasUsedOnPreparation { + let innerTxDataOffset := add(txDataOffset, 32) + + let gasBeforePreparation := gas() + debugLog("gasBeforePreparation", gasBeforePreparation) + + // Even though the smart contracts on L1 should make sure that the L1->L2 provide enough gas to generate the hash + // we should still be able to do it even if this protection layer fails. + canonicalL1TxHash := getCanonicalL1TxHash(txDataOffset) + debugLog("l1 hash", canonicalL1TxHash) + + // Appending the transaction's hash to the current L2 block + appendTransactionHash(canonicalL1TxHash, true) + + markFactoryDepsForTx(innerTxDataOffset, true) + + gasUsedOnPreparation := safeSub(gasBeforePreparation, gas(), "xpa") + debugLog("gasUsedOnPreparation", gasUsedOnPreparation) + } + + /// @dev Returns the gas price that should be used by the transaction + /// based on the EIP1559's maxFeePerGas and maxPriorityFeePerGas. + /// The following invariants should hold: + /// maxPriorityFeePerGas <= maxFeePerGas + /// baseFee <= maxFeePerGas + /// While we charge baseFee from the users, the method is mostly used as a method for validating + /// the correctness of the fee parameters + function getGasPrice( + maxFeePerGas, + maxPriorityFeePerGas + ) -> ret { + let baseFee := basefee() + + if gt(maxPriorityFeePerGas, maxFeePerGas) { + revertWithReason( + MAX_PRIORITY_FEE_PER_GAS_GREATER_THAN_MAX_FEE_PER_GAS(), + 0 + ) + } + + if gt(baseFee, maxFeePerGas) { + revertWithReason( + BASE_FEE_GREATER_THAN_MAX_FEE_PER_GAS(), + 0 + ) + } + + // We always use `baseFee` to charge the transaction + ret := baseFee + } + + /// @dev The function responsible for processing L2 transactions. + /// @param txDataOffset The offset to the ABI-encoded Transaction struct. + /// @param resultPtr The pointer at which the result of the execution of this transaction + /// should be stored. + /// @param transactionIndex The index of the current transaction. + /// @param gasPerPubdata The L2 gas to be used for each byte of pubdata published onchain. + /// @dev This function firstly does the validation step and then the execution step in separate near_calls. + /// It is important that these steps are split to avoid rollbacking the state made by the validation step. + function processL2Tx( + txDataOffset, + resultPtr, + transactionIndex, + gasPerPubdata + ) { + let innerTxDataOffset := add(txDataOffset, 32) + + // Firsly, we publish all the bytecodes needed. This is needed to be done separately, since + // bytecodes usually form the bulk of the L2 gas prices. + + let gasLimitForTx, reservedGas := getGasLimitForTx(innerTxDataOffset, transactionIndex, gasPerPubdata, L2_TX_INTRINSIC_GAS(), L2_TX_INTRINSIC_PUBDATA()) + + let gasPrice := getGasPrice(getMaxFeePerGas(innerTxDataOffset), getMaxPriorityFeePerGas(innerTxDataOffset)) + + debugLog("gasLimitForTx", gasLimitForTx) + + let gasLeft := l2TxValidation( + txDataOffset, + gasLimitForTx, + gasPrice + ) + + debugLog("validation finished", 0) + + let gasSpentOnExecute := 0 + let success := 0 + success, gasSpentOnExecute := l2TxExecution(txDataOffset, gasLeft) + + debugLog("execution finished", 0) + + let refund := 0 + let gasToRefund := sub(gasLeft, gasSpentOnExecute) + if lt(gasLeft, gasSpentOnExecute){ + gasToRefund := 0 + } + + // Note, that we pass reservedGas from the refundGas separately as it should not be used + // during the postOp execution. + refund := refundCurrentL2Transaction( + txDataOffset, + transactionIndex, + success, + gasToRefund, + gasPrice, + reservedGas + ) + + debugLog("refund", 0) + + notifyAboutRefund(refund) + mstore(resultPtr, success) + } + + /// @dev Calculates the L2 gas limit for the transaction's body, i.e. without intrinsic costs and overhead. + /// @param innerTxDataOffset The offset for the ABI-encoded Transaction struct fields. + /// @param transactionIndex The index of the transaction within the batch. + /// @param gasPerPubdata The price for a pubdata byte in L2 gas. + /// @param intrinsicGas The intrinsic number of L2 gas required for transaction processing. + /// @param intrinsicPubdata The intrinsic number of pubdata bytes required for transaction processing. + /// @return gasLimitForTx The maximum number of L2 gas that can be spent on a transaction. + /// @return reservedGas The number of L2 gas that is beyond the `MAX_GAS_PER_TRANSACTION` and beyond the operator's trust limit, + /// i.e. gas which we cannot allow the transaction to use and will refund. + function getGasLimitForTx( + innerTxDataOffset, + transactionIndex, + gasPerPubdata, + intrinsicGas, + intrinsicPubdata + ) -> gasLimitForTx, reservedGas { + let totalGasLimit := getGasLimit(innerTxDataOffset) + + // `MAX_GAS_PER_TRANSACTION` is the amount of gas each transaction + // is guaranteed to get, so even if the operator does not trust the account enough, + // it is still obligated to provide at least that + let operatorTrustedGasLimit := max(MAX_GAS_PER_TRANSACTION(), getOperatorTrustedGasLimitForTx(transactionIndex)) + + // We remember the amount of gas that is beyond the operator's trust limit to refund it back later. + switch gt(totalGasLimit, operatorTrustedGasLimit) + case 0 { + reservedGas := 0 + } + default { + reservedGas := sub(totalGasLimit, operatorTrustedGasLimit) + totalGasLimit := operatorTrustedGasLimit + } + + let txEncodingLen := safeAdd(32, getDataLength(innerTxDataOffset), "lsh") + + let operatorOverheadForTransaction := getVerifiedOperatorOverheadForTx( + transactionIndex, + totalGasLimit, + gasPerPubdata, + txEncodingLen + ) + gasLimitForTx := safeSub(totalGasLimit, operatorOverheadForTransaction, "qr") + + let intrinsicOverhead := safeAdd( + intrinsicGas, + // the error messages are trimmed to fit into 32 bytes + safeMul(intrinsicPubdata, gasPerPubdata, "qw"), + "fj" + ) + + switch lt(gasLimitForTx, intrinsicOverhead) + case 1 { + gasLimitForTx := 0 + } + default { + gasLimitForTx := sub(gasLimitForTx, intrinsicOverhead) + } + } + + /// @dev The function responsible for the L2 transaction validation. + /// @param txDataOffset The offset to the ABI-encoded Transaction struct. + /// @param gasLimitForTx The L2 gas limit for the transaction validation & execution. + /// @param gasPrice The L2 gas price that should be used by the transaction. + /// @return gasLeft The gas left after the validation step. + function l2TxValidation( + txDataOffset, + gasLimitForTx, + gasPrice + ) -> gasLeft { + let gasBeforeValidate := gas() + + debugLog("gasBeforeValidate", gasBeforeValidate) + + // Saving the tx hash and the suggested signed tx hash to memory + saveTxHashes(txDataOffset) + + // Appending the transaction's hash to the current L2 block + appendTransactionHash(mload(CURRENT_L2_TX_HASHES_BEGIN_BYTE()), false) + + checkEnoughGas(gasLimitForTx) + + // Note, that it is assumed that `ZKSYNC_NEAR_CALL_validateTx` will always return true + // unless some error which made the whole bootloader to revert has happened or + // it runs out of gas. + let isValid := 0 + + // Only if the gasLimit for tx is non-zero, we will try to actually run the validation + if gasLimitForTx { + let validateABI := getNearCallABI(gasLimitForTx) + + debugLog("validateABI", validateABI) + + isValid := ZKSYNC_NEAR_CALL_validateTx(validateABI, txDataOffset, gasPrice) + } + + debugLog("isValid", isValid) + + let gasUsedForValidate := sub(gasBeforeValidate, gas()) + debugLog("gasUsedForValidate", gasUsedForValidate) + + gasLeft := sub(gasLimitForTx, gasUsedForValidate) + if lt(gasLimitForTx, gasUsedForValidate) { + gasLeft := 0 + } + + // isValid can only be zero if the validation has failed with out of gas + if or(iszero(gasLeft), iszero(isValid)) { + revertWithReason(TX_VALIDATION_OUT_OF_GAS(), 0) + } + + setHook(VM_HOOK_VALIDATION_STEP_ENDED()) + } + + /// @dev The function responsible for the execution step of the L2 transaction. + /// @param txDataOffset The offset to the ABI-encoded Transaction struct. + /// @param gasLeft The gas left after the validation step. + /// @return success Whether or not the execution step was successful. + /// @return gasSpentOnExecute The gas spent on the transaction execution. + function l2TxExecution( + txDataOffset, + gasLeft, + ) -> success, gasSpentOnExecute { + let newCompressedFactoryDepsPointer := 0 + let gasSpentOnFactoryDeps := 0 + let gasBeforeFactoryDeps := gas() + if gasLeft { + let markingDependenciesABI := getNearCallABI(gasLeft) + checkEnoughGas(gasLeft) + newCompressedFactoryDepsPointer := ZKSYNC_NEAR_CALL_markFactoryDepsL2(markingDependenciesABI, txDataOffset) + gasSpentOnFactoryDeps := sub(gasBeforeFactoryDeps, gas()) + } + + // If marking of factory dependencies has been unsuccessful, 0 value is returned. + // Otherwise, all the previous dependencies have been successfully published, so + // we need to move the pointer. + if newCompressedFactoryDepsPointer { + mstore(COMPRESSED_BYTECODES_BEGIN_BYTE(), newCompressedFactoryDepsPointer) + } + + switch gt(gasLeft, gasSpentOnFactoryDeps) + case 0 { + gasSpentOnExecute := gasLeft + gasLeft := 0 + } + default { + // Note, that since gt(gasLeft, gasSpentOnFactoryDeps) = true + // sub(gasLeft, gasSpentOnFactoryDeps) > 0, which is important + // because a nearCall with 0 gas passes on all the gas of the parent frame. + gasLeft := sub(gasLeft, gasSpentOnFactoryDeps) + + let executeABI := getNearCallABI(gasLeft) + checkEnoughGas(gasLeft) + + let gasBeforeExecute := gas() + // for this one, we don't care whether or not it fails. + success := ZKSYNC_NEAR_CALL_executeL2Tx( + executeABI, + txDataOffset + ) + + gasSpentOnExecute := add(gasSpentOnFactoryDeps, sub(gasBeforeExecute, gas())) + } + + notifyExecutionResult(success) + } + + /// @dev Function responsible for the validation & fee payment step of the transaction. + /// @param abi The nearCall ABI. It is implicitly used as gasLimit for the call of this function. + /// @param txDataOffset The offset to the ABI-encoded Transaction struct. + /// @param gasPrice The gasPrice to be used in this transaction. + function ZKSYNC_NEAR_CALL_validateTx( + abi, + txDataOffset, + gasPrice + ) -> ret { + // For the validation step we always use the bootloader as the tx.origin of the transaction + setTxOrigin(BOOTLOADER_FORMAL_ADDR()) + setGasPrice(gasPrice) + + // Skipping the first 0x20 word of the ABI-encoding + let innerTxDataOffset := add(txDataOffset, 32) + debugLog("Starting validation", 0) + + accountValidateTx(txDataOffset) + debugLog("Tx validation complete", 1) + + ensurePayment(txDataOffset, gasPrice) + + ret := 1 + } + + /// @dev Function responsible for the execution of the L2 transaction. + /// It includes both the call to the `executeTransaction` method of the account + /// and the call to postOp of the account. + /// @param abi The nearCall ABI. It is implicitly used as gasLimit for the call of this function. + /// @param txDataOffset The offset to the ABI-encoded Transaction struct. + function ZKSYNC_NEAR_CALL_executeL2Tx( + abi, + txDataOffset + ) -> success { + // Skipping the first word of the ABI-encoding encoding + let innerTxDataOffset := add(txDataOffset, 32) + let from := getFrom(innerTxDataOffset) + + debugLog("Executing L2 tx", 0) + // The tx.origin can only be an EOA + switch isEOA(from) + case true { + setTxOrigin(from) + } + default { + setTxOrigin(BOOTLOADER_FORMAL_ADDR()) + } + + success := executeL2Tx(txDataOffset, from) + debugLog("Executing L2 ret", success) + } + + /// @dev Sets factory dependencies for an L2 transaction with possible usage of packed bytecodes. + function ZKSYNC_NEAR_CALL_markFactoryDepsL2( + abi, + txDataOffset + ) -> newDataInfoPtr { + let innerTxDataOffset := add(txDataOffset, 32) + + /// Note, that since it is the near call when it panics it reverts the state changes, but it DOES NOT + /// revert the changes in *memory* of the current frame. That is why we do not change the value under + /// COMPRESSED_BYTECODES_BEGIN_BYTE(), and it is only changed outside of this method. + let dataInfoPtr := mload(COMPRESSED_BYTECODES_BEGIN_BYTE()) + let factoryDepsPtr := getFactoryDepsPtr(innerTxDataOffset) + let factoryDepsLength := mload(factoryDepsPtr) + + let iter := add(factoryDepsPtr, 32) + let endPtr := add(iter, mul(32, factoryDepsLength)) + + for { } lt(iter, endPtr) { iter := add(iter, 32)} { + let bytecodeHash := mload(iter) + + let currentExpectedBytecodeHash := mload(dataInfoPtr) + + if eq(bytecodeHash, currentExpectedBytecodeHash) { + // Here we are making sure that the bytecode is indeed not yet know and needs to be published, + // preveting users from being overcharged by the operator. + let marker := getCodeMarker(bytecodeHash) + + if marker { + assertionError("invalid republish") + } + + dataInfoPtr := sendCompressedBytecode(dataInfoPtr, bytecodeHash) + } + } + + // For all the bytecodes that have not been compressed on purpose or due to the inefficiency + // of compressing the entire preimage of the bytecode will be published. + // For bytecodes published in the previous step, no need pubdata will have to be published + markFactoryDepsForTx(innerTxDataOffset, false) + + newDataInfoPtr := dataInfoPtr + } + + function getCodeMarker(bytecodeHash) -> ret { + mstore(0, {{GET_MARKER_PADDED_SELECTOR}}) + mstore(4, bytecodeHash) + let success := call( + gas(), + KNOWN_CODES_CONTRACT_ADDR(), + 0, + 0, + 36, + 0, + 32 + ) + + if iszero(success) { + nearCallPanic() + } + + ret := mload(0) + } + + + /// @dev Used to refund the current transaction. + /// The gas that this transaction consumes has been already paid in the + /// process of the validation + function refundCurrentL2Transaction( + txDataOffset, + transactionIndex, + success, + gasLeft, + gasPrice, + reservedGas + ) -> finalRefund { + setTxOrigin(BOOTLOADER_FORMAL_ADDR()) + + finalRefund := 0 + + let innerTxDataOffset := add(txDataOffset, 32) + + let paymaster := getPaymaster(innerTxDataOffset) + let refundRecipient := 0 + switch paymaster + case 0 { + // No paymaster means that the sender should receive the refund + refundRecipient := getFrom(innerTxDataOffset) + } + default { + refundRecipient := paymaster + + if gt(gasLeft, 0) { + checkEnoughGas(gasLeft) + let nearCallAbi := getNearCallABI(gasLeft) + let gasBeforePostOp := gas() + pop(ZKSYNC_NEAR_CALL_callPostOp( + // Maximum number of gas that the postOp could spend + nearCallAbi, + paymaster, + txDataOffset, + success, + // Since the paymaster will be refunded with reservedGas, + // it should know about it + safeAdd(gasLeft, reservedGas, "jkl") + )) + let gasSpentByPostOp := sub(gasBeforePostOp, gas()) + + switch gt(gasLeft, gasSpentByPostOp) + case 1 { + gasLeft := sub(gasLeft, gasSpentByPostOp) + } + default { + gasLeft := 0 + } + } + } + + askOperatorForRefund(gasLeft) + + let operatorProvidedRefund := getOperatorRefundForTx(transactionIndex) + + // If the operator provides the value that is lower than the one suggested for + // the bootloader, we will use the one calculated by the bootloader. + let refundInGas := max(operatorProvidedRefund, add(reservedGas, gasLeft)) + + // The operator cannot refund more than the gasLimit for the transaction + if gt(refundInGas, getGasLimit(innerTxDataOffset)) { + assertionError("refundInGas > gasLimit") + } + + if iszero(validateUint32(refundInGas)) { + assertionError("refundInGas is not uint32") + } + + let ethToRefund := safeMul( + refundInGas, + gasPrice, + "fdf" + ) + + directETHTransfer(ethToRefund, refundRecipient) + + finalRefund := refundInGas + } + + /// @notice A function that transfers ETH directly through the L2EthToken system contract. + /// Note, that unlike classical EVM transfers it does NOT call the recipient, but only changes the balance. + function directETHTransfer(amount, recipient) { + let ptr := 0 + mstore(ptr, {{PADDED_TRANSFER_FROM_TO_SELECTOR}}) + mstore(add(ptr, 4), BOOTLOADER_FORMAL_ADDR()) + mstore(add(ptr, 36), recipient) + mstore(add(ptr, 68), amount) + + let transferSuccess := call( + gas(), + ETH_L2_TOKEN_ADDR(), + 0, + 0, + 100, + 0, + 0 + ) + + if iszero(transferSuccess) { + assertionError("Failed to refund") + } + } + + /// @dev Return the operator suggested transaction refund. + function getOperatorRefundForTx(transactionIndex) -> ret { + let refundPtr := add(TX_OPERATOR_REFUND_BEGIN_BYTE(), mul(transactionIndex, 32)) + ret := mload(refundPtr) + } + + /// @dev Return the operator suggested transaction overhead cost. + function getOperatorOverheadForTx(transactionIndex) -> ret { + let txBatchOverheadPtr := add(TX_SUGGESTED_OVERHEAD_BEGIN_BYTE(), mul(transactionIndex, 32)) + ret := mload(txBatchOverheadPtr) + } + + /// @dev Return the operator's "trusted" transaction gas limit + function getOperatorTrustedGasLimitForTx(transactionIndex) -> ret { + let txTrustedGasLimitPtr := add(TX_OPERATOR_TRUSTED_GAS_LIMIT_BEGIN_BYTE(), mul(transactionIndex, 32)) + ret := mload(txTrustedGasLimitPtr) + } + + /// @dev Returns the bytecode hash that is next for being published + function getCurrentCompressedBytecodeHash() -> ret { + let compressionPtr := mload(COMPRESSED_BYTECODES_BEGIN_BYTE()) + + ret := mload(add(COMPRESSED_BYTECODES_BEGIN_BYTE(), compressionPtr)) + } + + function checkOffset(pointer) { + if gt(pointer, sub(COMPRESSED_BYTECODES_END_BYTE(), MIN_ALLOWED_OFFSET_FOR_COMPRESSED_BYTES_POINTER())) { + assertionError("calldataEncoding too big") + } + } + + /// @dev It is expected that the pointer at the COMPRESSED_BYTECODES_BEGIN_BYTE() + /// stores the position of the current bytecodeHash + function sendCompressedBytecode(dataInfoPtr, bytecodeHash) -> ret { + // Storing the right selector, ensuring that the operator cannot manipulate it + mstore(add(dataInfoPtr, 32), {{PUBLISH_COMPRESSED_BYTECODE_SELECTOR}}) + + let calldataPtr := add(dataInfoPtr, 60) + let afterSelectorPtr := add(calldataPtr, 4) + + let originalBytecodeOffset := add(mload(afterSelectorPtr), afterSelectorPtr) + checkOffset(originalBytecodeOffset) + let potentialRawCompressedDataOffset := validateBytes( + originalBytecodeOffset + ) + + let rawCompressedDataOffset := add(mload(add(afterSelectorPtr, 32)), afterSelectorPtr) + checkOffset(rawCompressedDataOffset) + + if iszero(eq(potentialRawCompressedDataOffset, rawCompressedDataOffset)) { + assertionError("Compression calldata incorrect") + } + + let nextAfterCalldata := validateBytes( + rawCompressedDataOffset + ) + checkOffset(nextAfterCalldata) + + let totalLen := safeSub(nextAfterCalldata, calldataPtr, "xqwf") + + // Note, that it is safe because the + let success := call( + gas(), + BYTECODE_COMPRESSOR_ADDR(), + 0, + calldataPtr, + totalLen, + 0, + 32 + ) + + // If the transaction failed, the most likely reason is that there + // was not enough gas. That's why we do the nearCallPanic to stop the near call frame. + if iszero(success) { + debugLog("compressor call failed", 0) + debugReturndata() + nearCallPanic() + } + + let returnedBytecodeHash := mload(0) + + // If the bytecode hash calculated on the bytecode compressor's side + // is not equal to the one provided by the operator means that the operator is + // malicious and we should revert the batch altogether + if iszero(eq(returnedBytecodeHash, bytecodeHash)) { + assertionError("bytecodeHash incorrect") + } + + ret := nextAfterCalldata + } + + /// @dev Get checked for overcharged operator's overhead for the transaction. + /// @param transactionIndex The index of the transaction in the batch + /// @param txTotalGasLimit The total gass limit of the transaction (including the overhead). + /// @param gasPerPubdataByte The price for pubdata byte in gas. + /// @param txEncodeLen The length of the ABI-encoding of the transaction + function getVerifiedOperatorOverheadForTx( + transactionIndex, + txTotalGasLimit, + gasPerPubdataByte, + txEncodeLen + ) -> ret { + let operatorOverheadForTransaction := getOperatorOverheadForTx(transactionIndex) + if gt(operatorOverheadForTransaction, txTotalGasLimit) { + assertionError("Overhead higher than gasLimit") + } + let txGasLimit := min(safeSub(txTotalGasLimit, operatorOverheadForTransaction, "www"), MAX_GAS_PER_TRANSACTION()) + + let requiredOverhead := getTransactionUpfrontOverhead( + txGasLimit, + gasPerPubdataByte, + txEncodeLen + ) + + debugLog("txTotalGasLimit", txTotalGasLimit) + debugLog("requiredOverhead", requiredOverhead) + debugLog("operatorOverheadForTransaction", operatorOverheadForTransaction) + + // The required overhead is less than the overhead that the operator + // has requested from the user, meaning that the operator tried to overcharge the user + if lt(requiredOverhead, operatorOverheadForTransaction) { + assertionError("Operator's overhead too high") + } + + ret := operatorOverheadForTransaction + } + + /// @dev Function responsible for the execution of the L1->L2 transaction. + /// @param abi The nearCall ABI. It is implicitly used as gasLimit for the call of this function. + /// @param txDataOffset The offset to the ABI-encoded Transaction struct. + function ZKSYNC_NEAR_CALL_executeL1Tx( + abi, + txDataOffset + ) -> success { + // Skipping the first word of the ABI encoding of the struct + let innerTxDataOffset := add(txDataOffset, 32) + let from := getFrom(innerTxDataOffset) + let gasPrice := getMaxFeePerGas(innerTxDataOffset) + + debugLog("Executing L1 tx", 0) + debugLog("from", from) + debugLog("gasPrice", gasPrice) + + // We assume that addresses of smart contracts on zkSync and Ethereum + // never overlap, so no need to check whether `from` is an EOA here. + debugLog("setting tx origin", from) + + setTxOrigin(from) + debugLog("setting gas price", gasPrice) + + setGasPrice(gasPrice) + + debugLog("execution itself", 0) + + let value := getValue(innerTxDataOffset) + if value { + mintEther(from, value, true) + } + + success := executeL1Tx(innerTxDataOffset, from) + + debugLog("Executing L1 ret", success) + + // If the success is zero, we will revert in order + // to revert the minting of ether to the user + if iszero(success) { + nearCallPanic() + } + } + + /// @dev Returns the ABI for nearCalls. + /// @param gasLimit The gasLimit for this nearCall + function getNearCallABI(gasLimit) -> ret { + ret := gasLimit + } + + /// @dev Used to panic from the nearCall without reverting the parent frame. + /// If you use `revert(...)`, the error will bubble up from the near call and + /// make the bootloader to revert as well. This method allows to exit the nearCall only. + function nearCallPanic() { + // Here we exhaust all the gas of the current frame. + // This will cause the execution to panic. + // Note, that it will cause only the inner call to panic. + precompileCall(gas()) + } + + /// @dev Executes the `precompileCall` opcode. + /// Since the bootloader has no implicit meaning for this opcode, + /// this method just burns gas. + function precompileCall(gasToBurn) { + // We don't care about the return value, since it is a opcode simulation + // and the return value doesn't have any meaning. + let ret := verbatim_2i_1o("precompile", 0, gasToBurn) + } + + /// @dev Returns the pointer to the latest returndata. + function returnDataPtr() -> ret { + ret := verbatim_0i_1o("get_global::ptr_return_data") + } + + + + function ZKSYNC_NEAR_CALL_ethCall( + abi, + txDataOffset, + resultPtr + ) { + let innerTxDataOffset := add(txDataOffset, 32) + let to := getTo(innerTxDataOffset) + let from := getFrom(innerTxDataOffset) + + debugLog("from: ", from) + debugLog("to: ", to) + + switch isEOA(from) + case true { + setTxOrigin(from) + } + default { + setTxOrigin(0) + } + + let dataPtr := getDataPtr(innerTxDataOffset) + markFactoryDepsForTx(innerTxDataOffset, false) + + let value := getValue(innerTxDataOffset) + + let success := msgValueSimulatorMimicCall( + to, + from, + value, + dataPtr + ) + + if iszero(success) { + // If success is 0, we need to revert + revertWithReason( + ETH_CALL_ERR_CODE(), + 1 + ) + } + + mstore(resultPtr, success) + + // Store results of the call in the memory. + if success { + let returnsize := returndatasize() + returndatacopy(0,0,returnsize) + return(0,returnsize) + } + + } + + + /// @dev Given the callee and the data to be called with, + /// this function returns whether the mimicCall should use the `isSystem` flag. + /// This flag should only be used for contract deployments and nothing else. + /// @param to The callee of the call. + /// @param dataPtr The pointer to the calldata of the transaction. + function shouldMsgValueMimicCallBeSystem(to, dataPtr) -> ret { + let dataLen := mload(dataPtr) + // Note, that this point it is not fully known whether it is indeed the selector + // of the calldata (it might not be the case if the `dataLen` < 4), but it will be checked later on + let selector := shr(224, mload(add(dataPtr, 32))) + + let isSelectorCreate := or( + eq(selector, {{CREATE_SELECTOR}}), + eq(selector, {{CREATE_ACCOUNT_SELECTOR}}) + ) + let isSelectorCreate2 := or( + eq(selector, {{CREATE2_SELECTOR}}), + eq(selector, {{CREATE2_ACCOUNT_SELECTOR}}) + ) + + // Firstly, ensure that the selector is a valid deployment function + ret := or( + isSelectorCreate, + isSelectorCreate2 + ) + // Secondly, ensure that the callee is ContractDeployer + ret := and(ret, eq(to, CONTRACT_DEPLOYER_ADDR())) + // Thirdly, ensure that the calldata is long enough to contain the selector + ret := and(ret, gt(dataLen, 3)) + } + + /// @dev Given the pointer to the calldata, the value and to + /// performs the call through the msg.value simulator. + /// @param to Which contract to call + /// @param from The `msg.sender` of the call. + /// @param value The `value` that will be used in the call. + /// @param dataPtr The pointer to the calldata of the transaction. It must store + /// the length of the calldata and the calldata itself right afterwards. + function msgValueSimulatorMimicCall(to, from, value, dataPtr) -> success { + // Only calls to the deployer system contract are allowed to be system + let isSystem := shouldMsgValueMimicCallBeSystem(to, dataPtr) + + success := mimicCallOnlyResult( + MSG_VALUE_SIMULATOR_ADDR(), + from, + dataPtr, + 0, + 1, + value, + to, + isSystem + ) + } + + /// @dev Checks whether the current frame has enough gas + /// @dev It does not use 63/64 rule and should only be called before nearCalls. + function checkEnoughGas(gasToProvide) { + debugLog("gas()", gas()) + debugLog("gasToProvide", gasToProvide) + + // Using margin of CHECK_ENOUGH_GAS_OVERHEAD gas to make sure that the operation will indeed + // have enough gas + if lt(gas(), safeAdd(gasToProvide, CHECK_ENOUGH_GAS_OVERHEAD(), "cjq")) { + revertWithReason(NOT_ENOUGH_GAS_PROVIDED_ERR_CODE(), 0) + } + } + + /// Returns the batch overhead to be paid, assuming a certain value of gasPerPubdata + function getBatchOverheadGas(gasPerPubdata) -> ret { + let computationOverhead := BATCH_OVERHEAD_L2_GAS() + let l1GasOverhead := BATCH_OVERHEAD_L1_GAS() + let l1GasPerPubdata := L1_GAS_PER_PUBDATA_BYTE() + + // Since the user specifies the amount of gas he is willing to pay for a *byte of pubdata*, + // we need to convert the number of L1 gas needed to process the batch into the equivalent number of + // pubdata to pay for. + // The difference between ceil and floor division here is negligible, + // so we prefer doing the cheaper operation for the end user + let pubdataEquivalentForL1Gas := safeDiv(l1GasOverhead, l1GasPerPubdata, "dd") + + ret := safeAdd( + computationOverhead, + safeMul(gasPerPubdata, pubdataEquivalentForL1Gas, "aa"), + "ab" + ) + } + + /// @dev This method returns the overhead that should be paid upfront by a transaction. + /// The goal of this overhead is to cover the possibility that this transaction may use up a certain + /// limited resource per batch: a single-instance circuit, etc. + /// The transaction needs to be able to pay the same % of the costs for publishing & proving the batch + /// as the % of the batch's limited resources that it can consume. + /// @param txGasLimit The gasLimit for the transaction (note, that this limit should not include the overhead). + /// @param gasPerPubdataByte The price for pubdata byte in gas. + /// @param txEncodeLen The length of the ABI-encoding of the transaction + /// @dev The % following 3 resources is taken into account when calculating the % of the batch's overhead to pay. + /// 1. The % of the maximal gas per transaction. It is assumed that `MAX_GAS_PER_TRANSACTION` gas is enough to consume all + /// the single-instance circuits. Meaning that the transaction should pay at least txGasLimit/MAX_GAS_PER_TRANSACTION part + /// of the overhead. + /// 2. Overhead for taking up the bootloader memory. The bootloader memory has a cap on its length, mainly enforced to keep the RAM requirements + /// for the node smaller. That is, the user needs to pay a share proportional to the length of the ABI encoding of the transaction. + /// 3. Overhead for taking up a slot for the transaction. Since each batch has the limited number of transactions in it, the user must pay + /// at least 1/MAX_TRANSACTIONS_IN_BATCH part of the overhead. + function getTransactionUpfrontOverhead( + txGasLimit, + gasPerPubdataByte, + txEncodeLen + ) -> ret { + ret := 0 + let totalBatchOverhead := getBatchOverheadGas(gasPerPubdataByte) + debugLog("totalBatchOverhead", totalBatchOverhead) + + let overheadForCircuits := ceilDiv( + safeMul(totalBatchOverhead, txGasLimit, "ac"), + MAX_GAS_PER_TRANSACTION() + ) + ret := max(ret, overheadForCircuits) + debugLog("overheadForCircuits", overheadForCircuits) + + + let overheadForLength := ceilDiv( + safeMul(txEncodeLen, totalBatchOverhead, "ad"), + BOOTLOADER_MEMORY_FOR_TXS() + ) + ret := max(ret, overheadForLength) + debugLog("overheadForLength", overheadForLength) + + + let overheadForSlot := ceilDiv( + totalBatchOverhead, + MAX_TRANSACTIONS_IN_BATCH() + ) + ret := max(ret, overheadForSlot) + debugLog("overheadForSlot", overheadForSlot) + + // In the proved batch we ensure that the gasPerPubdataByte is not zero + // to avoid the potential edge case of division by zero. In Yul, division by + // zero does not panic, but returns zero. + + if and(iszero(gasPerPubdataByte), FORBID_ZERO_GAS_PER_PUBDATA()) { + assertionError("zero gasPerPubdataByte") + } + + } + + /// @dev A method where all panics in the nearCalls get to. + /// It is needed to prevent nearCall panics from bubbling up. + function ZKSYNC_CATCH_NEAR_CALL() { + debugLog("ZKSYNC_CATCH_NEAR_CALL",0) + setHook(VM_HOOK_CATCH_NEAR_CALL()) + } + + /// @dev Prepends the selector before the txDataOffset, + /// preparing it to be used to call either `verify` or `execute`. + /// Returns the pointer to the calldata. + /// Note, that this overrides 32 bytes before the current transaction: + function prependSelector(txDataOffset, selector) -> ret { + + let calldataPtr := sub(txDataOffset, 4) + // Note, that since `mstore` stores 32 bytes at once, we need to + // actually store the selector in one word starting with the + // (txDataOffset - 32) = (calldataPtr - 28) + mstore(sub(calldataPtr, 28), selector) + + ret := calldataPtr + } + + /// @dev Returns the maximum of two numbers + function max(x, y) -> ret { + ret := y + if gt(x, y) { + ret := x + } + } + + /// @dev Returns the minimum of two numbers + function min(x, y) -> ret { + ret := y + if lt(x, y) { + ret := x + } + } + + /// @dev Returns constant that is equal to `keccak256("")` + function EMPTY_STRING_KECCAK() -> ret { + ret := 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 + } + + /// @dev Returns whether x <= y + function lte(x, y) -> ret { + ret := or(lt(x,y), eq(x,y)) + } + + /// @dev Checks whether an address is an account + /// @param addr The address to check + function ensureAccount(addr) { + mstore(0, {{RIGHT_PADDED_GET_ACCOUNT_VERSION_SELECTOR}}) + mstore(4, addr) + + let success := call( + gas(), + CONTRACT_DEPLOYER_ADDR(), + 0, + 0, + 36, + 0, + 32 + ) + + let supportedVersion := mload(0) + + if iszero(success) { + revertWithReason( + FAILED_TO_CHECK_ACCOUNT_ERR_CODE(), + 1 + ) + } + + // This method returns AccountAbstractVersion enum. + // Currently only two versions are supported: 1 or 0, which basically + // mean whether the contract is an account or not. + if iszero(supportedVersion) { + revertWithReason( + FROM_IS_NOT_AN_ACCOUNT_ERR_CODE(), + 0 + ) + } + } + + /// @dev Checks whether an address is an EOA (i.e. has not code deployed on it) + /// @param addr The address to check + function isEOA(addr) -> ret { + mstore(0, {{RIGHT_PADDED_GET_RAW_CODE_HASH_SELECTOR}}) + mstore(4, addr) + let success := call( + gas(), + ACCOUNT_CODE_STORAGE_ADDR(), + 0, + 0, + 36, + 0, + 32 + ) + + if iszero(success) { + // The call to the account code storage should always succeed + nearCallPanic() + } + + let rawCodeHash := mload(0) + + ret := iszero(rawCodeHash) + } + + /// @dev Calls the `payForTransaction` method of an account + function accountPayForTx(account, txDataOffset) -> success { + success := callAccountMethod({{PAY_FOR_TX_SELECTOR}}, account, txDataOffset) + } + + /// @dev Calls the `prepareForPaymaster` method of an account + function accountPrePaymaster(account, txDataOffset) -> success { + success := callAccountMethod({{PRE_PAYMASTER_SELECTOR}}, account, txDataOffset) + } + + /// @dev Calls the `validateAndPayForPaymasterTransaction` method of a paymaster + function validateAndPayForPaymasterTransaction(paymaster, txDataOffset) -> success { + success := callAccountMethod({{VALIDATE_AND_PAY_PAYMASTER}}, paymaster, txDataOffset) + } + + /// @dev Used to call a method with the following signature; + /// someName( + /// bytes32 _txHash, + /// bytes32 _suggestedSignedHash, + /// Transaction calldata _transaction + /// ) + // Note, that this method expects that the current tx hashes are already stored + // in the `CURRENT_L2_TX_HASHES` slots. + function callAccountMethod(selector, account, txDataOffset) -> success { + // Safety invariant: it is safe to override data stored under + // `txDataOffset`, since the account methods are called only using + // `callAccountMethod` or `callPostOp` methods, both of which reformat + // the contents before innerTxDataOffset (i.e. txDataOffset + 32 bytes), + // i.e. make sure that the position at the txDataOffset has valid value. + let txDataWithHashesOffset := sub(txDataOffset, 64) + + // First word contains the canonical tx hash + let currentL2TxHashesPtr := CURRENT_L2_TX_HASHES_BEGIN_BYTE() + mstore(txDataWithHashesOffset, mload(currentL2TxHashesPtr)) + + // Second word contains the suggested tx hash for verifying + // signatures. + currentL2TxHashesPtr := add(currentL2TxHashesPtr, 32) + mstore(add(txDataWithHashesOffset, 32), mload(currentL2TxHashesPtr)) + + // Third word contains the offset of the main tx data (it is always 96 in our case) + mstore(add(txDataWithHashesOffset, 64), 96) + + let calldataPtr := prependSelector(txDataWithHashesOffset, selector) + let innerTxDataOffst := add(txDataOffset, 32) + + let len := getDataLength(innerTxDataOffst) + + // Besides the length of the transaction itself, + // we also require 3 words for hashes and the offset + // of the inner tx data. + let fullLen := add(len, 100) + + // The call itself. + success := call( + gas(), // The number of gas to pass. + account, // The address to call. + 0, // The `value` to pass. + calldataPtr, // The pointer to the calldata. + fullLen, // The size of the calldata, which is 4 for the selector + the actual length of the struct. + 0, // The pointer where the returned data will be written. + 0 // The output has size of 32 (a single bool is expected) + ) + } + + /// @dev Calculates and saves the explorer hash and the suggested signed hash for the transaction. + function saveTxHashes(txDataOffset) { + let calldataPtr := prependSelector(txDataOffset, {{GET_TX_HASHES_SELECTOR}}) + let innerTxDataOffst := add(txDataOffset, 32) + + let len := getDataLength(innerTxDataOffst) + + // The first word is formal, but still required by the ABI + // We also should take into account the selector. + let fullLen := add(len, 36) + + // The call itself. + let success := call( + gas(), // The number of gas to pass. + BOOTLOADER_UTILITIES(), // The address to call. + 0, // The `value` to pass. + calldataPtr, // The pointer to the calldata. + fullLen, // The size of the calldata, which is 4 for the selector + the actual length of the struct. + CURRENT_L2_TX_HASHES_BEGIN_BYTE(), // The pointer where the returned data will be written. + 64 // The output has size of 32 (signed tx hash and explorer tx hash are expected) + ) + + if iszero(success) { + revertWithReason( + ACCOUNT_TX_VALIDATION_ERR_CODE(), + 1 + ) + } + + if iszero(eq(returndatasize(), 64)) { + assertionError("saveTxHashes: returndata invalid") + } + } + + /// @dev Encodes and calls the postOp method of the contract. + /// Note, that it *breaks* the contents of the previous transactions. + /// @param abi The near call ABI of the call + /// @param paymaster The address of the paymaster + /// @param txDataOffset The offset to the ABI-encoded Transaction struct. + /// @param txResult The status of the transaction (1 if succeeded, 0 otherwise). + /// @param maxRefundedGas The maximum number of gas the bootloader can be refunded. + /// This is the `maximum` number because it does not take into account the number of gas that + /// can be spent by the paymaster itself. + function ZKSYNC_NEAR_CALL_callPostOp(abi, paymaster, txDataOffset, txResult, maxRefundedGas) -> success { + // The postOp method has the following signature: + // function postTransaction( + // bytes calldata _context, + // Transaction calldata _transaction, + // bytes32 _txHash, + // bytes32 _suggestedSignedHash, + // ExecutionResult _txResult, + // uint256 _maxRefundedGas + // ) external payable; + // The encoding is the following: + // 1. Offset to the _context's content. (32 bytes) + // 2. Offset to the _transaction's content. (32 bytes) + // 3. _txHash (32 bytes) + // 4. _suggestedSignedHash (32 bytes) + // 5. _txResult (32 bytes) + // 6. _maxRefundedGas (32 bytes) + // 7. _context (note, that the content must be padded to 32 bytes) + // 8. _transaction + + let contextLen := mload(PAYMASTER_CONTEXT_BEGIN_BYTE()) + let paddedContextLen := lengthRoundedByWords(contextLen) + // The length of selector + the first 7 fields (with context len) + context itself. + let preTxLen := add(228, paddedContextLen) + + let innerTxDataOffset := add(txDataOffset, 32) + let calldataPtr := sub(innerTxDataOffset, preTxLen) + + { + let ptr := calldataPtr + + // Selector + mstore(ptr, {{RIGHT_PADDED_POST_TRANSACTION_SELECTOR}}) + ptr := add(ptr, 4) + + // context ptr + mstore(ptr, 192) // The context always starts at 32 * 6 position + ptr := add(ptr, 32) + + // transaction ptr + mstore(ptr, sub(innerTxDataOffset, add(calldataPtr, 4))) + ptr := add(ptr, 32) + + // tx hash + mstore(ptr, mload(CURRENT_L2_TX_HASHES_BEGIN_BYTE())) + ptr := add(ptr, 32) + + // suggested signed hash + mstore(ptr, mload(add(CURRENT_L2_TX_HASHES_BEGIN_BYTE(), 32))) + ptr := add(ptr, 32) + + // tx result + mstore(ptr, txResult) + ptr := add(ptr, 32) + + // maximal refunded gas + mstore(ptr, maxRefundedGas) + ptr := add(ptr, 32) + + // storing context itself + memCopy(PAYMASTER_CONTEXT_BEGIN_BYTE(), ptr, add(32, paddedContextLen)) + ptr := add(ptr, add(32, paddedContextLen)) + + // At this point, the ptr should reach the innerTxDataOffset. + // If not, we have done something wrong here. + if iszero(eq(ptr, innerTxDataOffset)) { + assertionError("postOp: ptr != innerTxDataOffset") + } + + // no need to store the transaction as from the innerTxDataOffset starts + // valid encoding of the transaction + } + + let calldataLen := safeAdd(preTxLen, getDataLength(innerTxDataOffset), "jiq") + + success := call( + gas(), + paymaster, + 0, + calldataPtr, + calldataLen, + 0, + 0 + ) + } + + /// @dev Copies [from..from+len] to [to..to+len] + /// Note, that len must be divisible by 32. + function memCopy(from, to, len) { + // Ensuring that len is always divisible by 32. + if mod(len, 32) { + assertionError("Memcopy with unaligned length") + } + + let finalFrom := safeAdd(from, len, "cka") + + for { } lt(from, finalFrom) { + from := add(from, 32) + to := add(to, 32) + } { + mstore(to, mload(from)) + } + } + + /// @dev Validates the transaction against the senders' account. + /// Besides ensuring that the contract agrees to a transaction, + /// this method also enforces that the nonce has been marked as used. + function accountValidateTx(txDataOffset) { + // Skipping the first 0x20 word of the ABI-encoding of the struct + let innerTxDataOffst := add(txDataOffset, 32) + let from := getFrom(innerTxDataOffst) + ensureAccount(from) + + // The nonce should be unique for each transaction. + let nonce := getNonce(innerTxDataOffst) + // Here we check that this nonce was not available before the validation step + ensureNonceUsage(from, nonce, 0) + + setHook(VM_HOOK_ACCOUNT_VALIDATION_ENTERED()) + debugLog("pre-validate",0) + debugLog("pre-validate",from) + let success := callAccountMethod({{VALIDATE_TX_SELECTOR}}, from, txDataOffset) + setHook(VM_HOOK_NO_VALIDATION_ENTERED()) + + if iszero(success) { + revertWithReason( + ACCOUNT_TX_VALIDATION_ERR_CODE(), + 1 + ) + } + + ensureCorrectAccountMagic() + + // Here we make sure that the nonce is no longer available after the validation step + ensureNonceUsage(from, nonce, 1) + } + + /// @dev Ensures that the magic returned by the validate account method is correct + /// It must be called right after the call of the account validation method to preserve the + /// correct returndatasize + function ensureCorrectAccountMagic() { + // It is expected that the returned value is ABI-encoded bytes4 magic value + // The Solidity always pads such value to 32 bytes and so we expect the magic to be + // of length 32 + if iszero(eq(32, returndatasize())) { + revertWithReason( + ACCOUNT_RETURNED_INVALID_MAGIC_ERR_CODE(), + 0 + ) + } + + // Note that it is important to copy the magic even though it is not needed if the + // `SHOULD_ENSURE_CORRECT_RETURNED_MAGIC` is false. It is never false in production + // but it is so in fee estimation and we want to preserve as many operations as + // in the original operation. + returndatacopy(0, 0, 32) + let returnedValue := mload(0) + let isMagicCorrect := eq(returnedValue, {{SUCCESSFUL_ACCOUNT_VALIDATION_MAGIC_VALUE}}) + + if and(iszero(isMagicCorrect), SHOULD_ENSURE_CORRECT_RETURNED_MAGIC()) { + revertWithReason( + ACCOUNT_RETURNED_INVALID_MAGIC_ERR_CODE(), + 0 + ) + } + } + + /// @dev Calls the KnownCodesStorage system contract to mark the factory dependencies of + /// the transaction as known. + function markFactoryDepsForTx(innerTxDataOffset, isL1Tx) { + debugLog("starting factory deps", 0) + let factoryDepsPtr := getFactoryDepsPtr(innerTxDataOffset) + let factoryDepsLength := mload(factoryDepsPtr) + + if gt(factoryDepsLength, MAX_NEW_FACTORY_DEPS()) { + assertionError("too many factory deps") + } + + let ptr := NEW_FACTORY_DEPS_BEGIN_BYTE() + // Selector + mstore(ptr, {{MARK_BATCH_AS_REPUBLISHED_SELECTOR}}) + ptr := add(ptr, 32) + + // Saving whether the dependencies should be sent on L1 + // There is no need to send them for L1 transactions, since their + // preimages are already available on L1. + mstore(ptr, iszero(isL1Tx)) + ptr := add(ptr, 32) + + // Saving the offset to array (it is always 64) + mstore(ptr, 64) + ptr := add(ptr, 32) + + // Saving the array + + // We also need to include 32 bytes for the length itself + let arrayLengthBytes := safeAdd(32, safeMul(factoryDepsLength, 32, "ag"), "af") + // Copying factory deps array + memCopy(factoryDepsPtr, ptr, arrayLengthBytes) + + let success := call( + gas(), + KNOWN_CODES_CONTRACT_ADDR(), + 0, + // Shifting by 28 to start from the selector + add(NEW_FACTORY_DEPS_BEGIN_BYTE(), 28), + // 4 (selector) + 32 (send to l1 flag) + 32 (factory deps offset)+ 32 (factory deps length) + safeAdd(100, safeMul(factoryDepsLength, 32, "op"), "ae"), + 0, + 0 + ) + + debugLog("factory deps success", success) + + if iszero(success) { + debugReturndata() + switch isL1Tx + case 1 { + revertWithReason( + FAILED_TO_MARK_FACTORY_DEPS(), + 1 + ) + } + default { + // For L2 transactions, we use near call panic + nearCallPanic() + } + } + } + + /// @dev Function responsible for executing the L1->L2 transactions. + function executeL1Tx(innerTxDataOffset, from) -> ret { + let to := getTo(innerTxDataOffset) + debugLog("to", to) + let value := getValue(innerTxDataOffset) + debugLog("value", value) + let dataPtr := getDataPtr(innerTxDataOffset) + + let dataLength := mload(dataPtr) + let data := add(dataPtr, 32) + + ret := msgValueSimulatorMimicCall( + to, + from, + value, + dataPtr + ) + + if iszero(ret) { + debugReturndata() + } + } + + /// @dev Function responsible for the execution of the L2 transaction + /// @dev Returns `true` or `false` depending on whether or not the tx has reverted. + function executeL2Tx(txDataOffset, from) -> ret { + ret := callAccountMethod({{EXECUTE_TX_SELECTOR}}, from, txDataOffset) + + if iszero(ret) { + debugReturndata() + } + } + + /// + /// zkSync-specific utilities: + /// + + /// @dev Returns an ABI that can be used for low-level + /// invocations of calls and mimicCalls + /// @param dataPtr The pointer to the calldata. + /// @param gasPassed The number of gas to be passed with the call. + /// @param shardId The shard id of the callee. Currently only `0` (Rollup) is supported. + /// @param forwardingMode The mode of how the calldata is forwarded + /// It is possible to either pass a pointer, slice of auxheap or heap. For the + /// bootloader purposes using heap (0) is enough. + /// @param isConstructorCall Whether the call should contain the isConstructor flag. + /// @param isSystemCall Whether the call should contain the isSystemCall flag. + /// @return ret The ABI + function getFarCallABI( + dataPtr, + gasPassed, + shardId, + forwardingMode, + isConstructorCall, + isSystemCall + ) -> ret { + let dataStart := add(dataPtr, 32) + let dataLength := mload(dataPtr) + + // Skip dataOffset and memoryPage, because they are always zeros + ret := or(ret, shl(64, dataStart)) + ret := or(ret, shl(96, dataLength)) + + ret := or(ret, shl(192, gasPassed)) + ret := or(ret, shl(224, forwardingMode)) + ret := or(ret, shl(232, shardId)) + ret := or(ret, shl(240, isConstructorCall)) + ret := or(ret, shl(248, isSystemCall)) + } + + /// @dev Does mimicCall without copying the returndata. + /// @param to Who to call + /// @param whoToMimic The `msg.sender` of the call + /// @param data The pointer to the calldata + /// @param isConstructor Whether the call should contain the isConstructor flag + /// @param isSystemCall Whether the call should contain the isSystem flag. + /// @param extraAbi1 The first extraAbiParam + /// @param extraAbi2 The second extraAbiParam + /// @param extraAbi3 The third extraAbiParam + /// @return ret 1 if the call was successful, 0 otherwise. + function mimicCallOnlyResult( + to, + whoToMimic, + data, + isConstructor, + isSystemCall, + extraAbi1, + extraAbi2, + extraAbi3 + ) -> ret { + let farCallAbi := getFarCallABI( + data, + gas(), + // Only rollup is supported for now + 0, + 0, + isConstructor, + isSystemCall + ) + + ret := verbatim_7i_1o("system_mimic_call", to, whoToMimic, farCallAbi, extraAbi1, extraAbi2, extraAbi3, 0) + } + + + // Extracts the required byte from the 32-byte word. + // 31 would mean the MSB, 0 would mean LSB. + function getWordByte(word, byteIdx) -> ret { + // Shift the input to the right so the required byte is LSB + ret := shr(mul(8, byteIdx), word) + // Clean everything else in the word + ret := and(ret, 0xFF) + } + + + + /// @dev Sends a L2->L1 log using L1Messengers' `sendL2ToL1Log`. + /// @param isService The isService flag of the call. + /// @param key The `key` parameter of the log. + /// @param value The `value` parameter of the log. + function sendL2LogUsingL1Messenger(isService, key, value) { + mstore(0, {{RIGHT_PADDED_SEND_L2_TO_L1_LOG_SELECTOR}}) + mstore(4, isService) + mstore(36, key) + mstore(68, value) + + let success := call( + gas(), + L1_MESSENGER_ADDR(), + 0, + 0, + 100, + 0, + 0 + ) + + if iszero(success) { + debugLog("Failed to send L1Messenger L2Log", key) + debugLog("Failed to send L1Messenger L2Log", value) + + revertWithReason(L1_MESSENGER_LOG_SENDING_FAILED_ERR_CODE(), 1) + } + } + + /// @dev Sends a native (VM) L2->L1 log. + /// @param isService The isService flag of the call. + /// @param key The `key` parameter of the log. + /// @param value The `value` parameter of the log. + function sendToL1Native(isService, key, value) { + verbatim_3i_0o("to_l1", isService, key, value) + } + + /// @notice Performs L1 Messenger pubdata "publishing" call. + /// @dev Expected to be used at the end of the batch. + function l1MessengerPublishingCall() { + let ptr := OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_BEGIN_BYTE() + debugLog("Publishing batch data to L1", 0) + // First slot (only last 4 bytes) -- selector + mstore(ptr, {{PUBLISH_PUBDATA_SELECTOR}}) + // Second slot -- offset + mstore(add(ptr, 32), 32) + setHook(VM_HOOK_PUBDATA_REQUESTED()) + // Third slot -- length of pubdata + let len := mload(add(ptr, 64)) + // 4 bytes for selector, 32 bytes for array offset and 32 bytes for array length + let fullLen := add(len, 68) + + // ptr + 28 because the function selector only takes up the last 4 bytes in the first slot. + let success := call( + gas(), + L1_MESSENGER_ADDR(), + 0, + add(ptr, 28), + fullLen, + 0, + 0 + ) + + if iszero(success) { + debugLog("Failed to publish L2Logs data", 0) + + revertWithReason(L1_MESSENGER_PUBLISHING_FAILED_ERR_CODE(), 1) + } + } + + function publishTimestampDataToL1() { + debugLog("Publishing timestamp data to L1", 0) + + mstore(0, {{RIGHT_PADDED_PUBLISH_TIMESTAMP_DATA_TO_L1_SELECTOR}}) + let success := call( + gas(), + SYSTEM_CONTEXT_ADDR(), + 0, + 0, + 4, + 0, + 0 + ) + + if iszero(success) { + debugLog("Failed publish timestamp to L1", 0) + revertWithReason(FAILED_TO_PUBLISH_TIMESTAMP_DATA_TO_L1(), 1) + } + } + + /// @notice Performs a call of a System Context + /// method that have no input parameters + function callSystemContext(paddedSelector) { + mstore(0, paddedSelector) + + let success := call( + gas(), + SYSTEM_CONTEXT_ADDR(), + 0, + 0, + 4, + 0, + 0 + ) + + if iszero(success) { + debugLog("Failed to call System Context", 0) + + revertWithReason(FAILED_TO_CALL_SYSTEM_CONTEXT_ERR_CODE(), 1) + } + } + + /// @dev Increment the number of txs in the batch + function considerNewTx() { + verbatim_0i_0o("increment_tx_counter") + + callSystemContext({{RIGHT_PADDED_INCREMENT_TX_NUMBER_IN_BLOCK_SELECTOR}}) + } + + /// @dev Set the new price per pubdata byte + function setPricePerPubdataByte(newPrice) { + verbatim_1i_0o("set_pubdata_price", newPrice) + } + + /// @dev Set the new value for the tx origin context value + function setTxOrigin(newTxOrigin) { + let success := setContextVal({{RIGHT_PADDED_SET_TX_ORIGIN}}, newTxOrigin) + + if iszero(success) { + debugLog("Failed to set txOrigin", newTxOrigin) + nearCallPanic() + } + } + + /// @dev Set the new value for the gas price value + function setGasPrice(newGasPrice) { + let success := setContextVal({{RIGHT_PADDED_SET_GAS_PRICE}}, newGasPrice) + + if iszero(success) { + debugLog("Failed to set gas price", newGasPrice) + nearCallPanic() + } + } + + /// @notice Sets the context information for the current batch. + /// @dev The SystemContext.sol system contract is responsible for validating + /// the validity of the new batch's data. + function setNewBatch(prevBatchHash, newTimestamp, newBatchNumber, baseFee) { + mstore(0, {{RIGHT_PADDED_SET_NEW_BATCH_SELECTOR}}) + mstore(4, prevBatchHash) + mstore(36, newTimestamp) + mstore(68, newBatchNumber) + mstore(100, baseFee) + + let success := call( + gas(), + SYSTEM_CONTEXT_ADDR(), + 0, + 0, + 132, + 0, + 0 + ) + + if iszero(success) { + debugLog("Failed to set new batch: ", prevBatchHash) + debugLog("Failed to set new batch: ", newTimestamp) + + revertWithReason(FAILED_TO_SET_NEW_BATCH_ERR_CODE(), 1) + } + } + + /// @notice Sets the context information for the current L2 block. + /// @param txId The index of the transaction in the batch for which to get the L2 block information. + function setL2Block(txId) { + let txL2BlockPosition := add(TX_OPERATOR_L2_BLOCK_INFO_BEGIN_BYTE(), mul(TX_OPERATOR_L2_BLOCK_INFO_SIZE_BYTES(), txId)) + + let currentL2BlockNumber := mload(txL2BlockPosition) + let currentL2BlockTimestamp := mload(add(txL2BlockPosition, 32)) + let previousL2BlockHash := mload(add(txL2BlockPosition, 64)) + let virtualBlocksToCreate := mload(add(txL2BlockPosition, 96)) + + let isFirstInBatch := iszero(txId) + + debugLog("Setting new L2 block: ", currentL2BlockNumber) + debugLog("Setting new L2 block: ", currentL2BlockTimestamp) + debugLog("Setting new L2 block: ", previousL2BlockHash) + debugLog("Setting new L2 block: ", virtualBlocksToCreate) + + mstore(0, {{RIGHT_PADDED_SET_L2_BLOCK_SELECTOR}}) + mstore(4, currentL2BlockNumber) + mstore(36, currentL2BlockTimestamp) + mstore(68, previousL2BlockHash) + mstore(100, isFirstInBatch) + mstore(132, virtualBlocksToCreate) + + let success := call( + gas(), + SYSTEM_CONTEXT_ADDR(), + 0, + 0, + 164, + 0, + 0 + ) + + if iszero(success) { + debugLog("Failed to set new L2 block: ", currentL2BlockNumber) + debugLog("Failed to set new L2 block: ", currentL2BlockTimestamp) + debugLog("Failed to set new L2 block: ", previousL2BlockHash) + debugLog("Failed to set new L2 block: ", isFirstInBatch) + + revertWithReason(FAILED_TO_SET_L2_BLOCK(), 1) + } + } + + /// @notice Appends the transaction hash to the current L2 block. + /// @param txHash The hash of the transaction to append. + /// @param isL1Tx Whether the transaction is an L1 transaction. If it is an L1 transaction, + /// and this method fails, then the bootloader execution will be explicitly reverted. + /// Otherwise, the nearCallPanic will be used to implicitly fail the validation of the transaction. + function appendTransactionHash( + txHash, + isL1Tx + ) { + debugLog("Appending tx to L2 block", txHash) + + mstore(0, {{RIGHT_PADDED_APPEND_TRANSACTION_TO_L2_BLOCK_SELECTOR}}) + mstore(4, txHash) + + let success := call( + gas(), + SYSTEM_CONTEXT_ADDR(), + 0, + 0, + 36, + 0, + 0 + ) + + if iszero(success) { + debugReturndata() + switch isL1Tx + case 1 { + revertWithReason( + FAILED_TO_APPEND_TRANSACTION_TO_L2_BLOCK(), + 1 + ) + } + default { + // For L2 transactions, we use near call panic, it will triger the validation + // step of the transaction to fail, returning a consistent error message. + nearCallPanic() + } + } + } + + + /// @notice Arbitrarily overrides the current batch information. + /// @dev It should NOT be available in the proved batch. + function unsafeOverrideBatch(newTimestamp, newBatchNumber, baseFee) { + mstore(0, {{RIGHT_PADDED_OVERRIDE_BATCH_SELECTOR}}) + mstore(4, newTimestamp) + mstore(36, newBatchNumber) + mstore(68, baseFee) + + let success := call( + gas(), + SYSTEM_CONTEXT_ADDR(), + 0, + 0, + 100, + 0, + 0 + ) + + if iszero(success) { + debugLog("Failed to override batch: ", newTimestamp) + debugLog("Failed to override batch: ", newBatchNumber) + + revertWithReason(FAILED_TO_SET_NEW_BATCH_ERR_CODE(), 1) + } + } + + + + // Checks whether the nonce `nonce` have been already used for + // account `from`. Reverts if the nonce has not been used properly. + function ensureNonceUsage(from, nonce, shouldNonceBeUsed) { + // INonceHolder.validateNonceUsage selector + mstore(0, {{RIGHT_PADDED_VALIDATE_NONCE_USAGE_SELECTOR}}) + mstore(4, from) + mstore(36, nonce) + mstore(68, shouldNonceBeUsed) + + let success := call( + gas(), + NONCE_HOLDER_ADDR(), + 0, + 0, + 100, + 0, + 0 + ) + + if iszero(success) { + revertWithReason( + ACCOUNT_TX_VALIDATION_ERR_CODE(), + 1 + ) + } + } + + /// @dev Encodes and performs a call to a method of + /// `SystemContext.sol` system contract of the roughly the following interface: + /// someMethod(uint256 val) + function setContextVal( + selector, + value, + ) -> ret { + mstore(0, selector) + mstore(4, value) + + ret := call( + gas(), + SYSTEM_CONTEXT_ADDR(), + 0, + 0, + 36, + 0, + 0 + ) + } + + // Each of the txs have the following type: + // struct Transaction { + // // The type of the transaction. + // uint256 txType; + // // The caller. + // uint256 from; + // // The callee. + // uint256 to; + // // The gasLimit to pass with the transaction. + // // It has the same meaning as Ethereum's gasLimit. + // uint256 gasLimit; + // // The maximum amount of gas the user is willing to pay for a byte of pubdata. + // uint256 gasPerPubdataByteLimit; + // // The maximum fee per gas that the user is willing to pay. + // // It is akin to EIP1559's maxFeePerGas. + // uint256 maxFeePerGas; + // // The maximum priority fee per gas that the user is willing to pay. + // // It is akin to EIP1559's maxPriorityFeePerGas. + // uint256 maxPriorityFeePerGas; + // // The transaction's paymaster. If there is no paymaster, it is equal to 0. + // uint256 paymaster; + // // The nonce of the transaction. + // uint256 nonce; + // // The value to pass with the transaction. + // uint256 value; + // // In the future, we might want to add some + // // new fields to the struct. The `txData` struct + // // is to be passed to account and any changes to its structure + // // would mean a breaking change to these accounts. In order to prevent this, + // // we should keep some fields as "reserved". + // // It is also recommended that their length is fixed, since + // // it would allow easier proof integration (in case we will need + // // some special circuit for preprocessing transactions). + // uint256[4] reserved; + // // The transaction's calldata. + // bytes data; + // // The signature of the transaction. + // bytes signature; + // // The properly formatted hashes of bytecodes that must be published on L1 + // // with the inclusion of this transaction. Note, that a bytecode has been published + // // before, the user won't pay fees for its republishing. + // bytes32[] factoryDeps; + // // The input to the paymaster. + // bytes paymasterInput; + // // Reserved dynamic type for the future use-case. Using it should be avoided, + // // But it is still here, just in case we want to enable some additional functionality. + // bytes reservedDynamic; + // } + + /// @notice Asserts the equality of two values and reverts + /// with the appropriate error message in case it doesn't hold + /// @param value1 The first value of the assertion + /// @param value2 The second value of the assertion + /// @param message The error message + function assertEq(value1, value2, message) { + switch eq(value1, value2) + case 0 { assertionError(message) } + default { } + } + + /// @notice Makes sure that the structure of the transaction is set in accordance to its type + /// @dev This function validates only L2 transactions, since the integrity of the L1->L2 + /// transactions is enforced by the L1 smart contracts. + function validateTypedTxStructure(innerTxDataOffset) { + /// Some common checks for all transactions. + let reservedDynamicLength := getReservedDynamicBytesLength(innerTxDataOffset) + if gt(reservedDynamicLength, 0) { + assertionError("non-empty reservedDynamic") + } + let txType := getTxType(innerTxDataOffset) + switch txType + case 0 { + let maxFeePerGas := getMaxFeePerGas(innerTxDataOffset) + let maxPriorityFeePerGas := getMaxPriorityFeePerGas(innerTxDataOffset) + assertEq(maxFeePerGas, maxPriorityFeePerGas, "EIP1559 params wrong") + + + + let from := getFrom(innerTxDataOffset) + let iseoa := isEOA(from) + assertEq(iseoa, true, "Only EIP-712 can use non-EOA") + + + + // Here, for type 0 transactions the reserved0 field is used as a marker + // whether the transaction should include chainId in its encoding. + assertEq(lte(getGasPerPubdataByteLimit(innerTxDataOffset), MAX_L2_GAS_PER_PUBDATA()), 1, "Gas per pubdata is wrong") + assertEq(getPaymaster(innerTxDataOffset), 0, "paymaster non zero") + + + assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") + + + assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") + assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") + assertEq(getFactoryDepsBytesLength(innerTxDataOffset), 0, "factory deps non zero") + assertEq(getPaymasterInputBytesLength(innerTxDataOffset), 0, "paymasterInput non zero") + } + case 1 { + let maxFeePerGas := getMaxFeePerGas(innerTxDataOffset) + let maxPriorityFeePerGas := getMaxPriorityFeePerGas(innerTxDataOffset) + assertEq(maxFeePerGas, maxPriorityFeePerGas, "EIP1559 params wrong") + + + + let from := getFrom(innerTxDataOffset) + let iseoa := isEOA(from) + assertEq(iseoa, true, "Only EIP-712 can use non-EOA") + + + + assertEq(lte(getGasPerPubdataByteLimit(innerTxDataOffset), MAX_L2_GAS_PER_PUBDATA()), 1, "Gas per pubdata is wrong") + assertEq(getPaymaster(innerTxDataOffset), 0, "paymaster non zero") + + + assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") + + + assertEq(getReserved0(innerTxDataOffset), 0, "reserved0 non zero") + assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") + assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") + assertEq(getFactoryDepsBytesLength(innerTxDataOffset), 0, "factory deps non zero") + assertEq(getPaymasterInputBytesLength(innerTxDataOffset), 0, "paymasterInput non zero") + } + case 2 { + assertEq(lte(getGasPerPubdataByteLimit(innerTxDataOffset), MAX_L2_GAS_PER_PUBDATA()), 1, "Gas per pubdata is wrong") + assertEq(getPaymaster(innerTxDataOffset), 0, "paymaster non zero") + + + + let from := getFrom(innerTxDataOffset) + let iseoa := isEOA(from) + assertEq(iseoa, true, "Only EIP-712 can use non-EOA") + + + + + assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") + + + assertEq(getReserved0(innerTxDataOffset), 0, "reserved0 non zero") + assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") + assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") + assertEq(getFactoryDepsBytesLength(innerTxDataOffset), 0, "factory deps non zero") + assertEq(getPaymasterInputBytesLength(innerTxDataOffset), 0, "paymasterInput non zero") + } + case 113 { + let paymaster := getPaymaster(innerTxDataOffset) + assertEq(or(gt(paymaster, MAX_SYSTEM_CONTRACT_ADDR()), iszero(paymaster)), 1, "paymaster in kernel space") + + if iszero(paymaster) { + // Double checking that the paymasterInput is 0 if the paymaster is 0 + assertEq(getPaymasterInputBytesLength(innerTxDataOffset), 0, "paymasterInput non zero") + } + + + assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") + + assertEq(getReserved0(innerTxDataOffset), 0, "reserved0 non zero") + assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") + assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") + } + case 254 { + // Upgrade transaction, no need to validate as it is validated on L1. + } + case 255 { + // Double-check that the operator doesn't try to do an upgrade transaction via L1 -> L2 transaction. + assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") + // L1 transaction, no need to validate as it is validated on L1. + } + default { + assertionError("Unknown tx type") + } + } + + /// + /// TransactionData utilities + /// + /// @dev The next methods are programmatically generated + /// + + function getTxType(innerTxDataOffset) -> ret { + ret := mload(innerTxDataOffset) + } + + function getFrom(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 32)) + } + + function getTo(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 64)) + } + + function getGasLimit(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 96)) + } + + function getGasPerPubdataByteLimit(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 128)) + } + + function getMaxFeePerGas(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 160)) + } + + function getMaxPriorityFeePerGas(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 192)) + } + + function getPaymaster(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 224)) + } + + function getNonce(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 256)) + } + + function getValue(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 288)) + } + + function getReserved0(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 320)) + } + + function getReserved1(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 352)) + } + + function getReserved2(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 384)) + } + + function getReserved3(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 416)) + } + + function getDataPtr(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 448)) + ret := add(innerTxDataOffset, ret) + } + + function getDataBytesLength(innerTxDataOffset) -> ret { + let ptr := getDataPtr(innerTxDataOffset) + ret := lengthRoundedByWords(mload(ptr)) + } + + function getSignaturePtr(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 480)) + ret := add(innerTxDataOffset, ret) + } + + function getSignatureBytesLength(innerTxDataOffset) -> ret { + let ptr := getSignaturePtr(innerTxDataOffset) + ret := lengthRoundedByWords(mload(ptr)) + } + + function getFactoryDepsPtr(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 512)) + ret := add(innerTxDataOffset, ret) + } + + function getFactoryDepsBytesLength(innerTxDataOffset) -> ret { + let ptr := getFactoryDepsPtr(innerTxDataOffset) + ret := safeMul(mload(ptr),32, "fwop") + } + + function getPaymasterInputPtr(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 544)) + ret := add(innerTxDataOffset, ret) + } + + function getPaymasterInputBytesLength(innerTxDataOffset) -> ret { + let ptr := getPaymasterInputPtr(innerTxDataOffset) + ret := lengthRoundedByWords(mload(ptr)) + } + + function getReservedDynamicPtr(innerTxDataOffset) -> ret { + ret := mload(add(innerTxDataOffset, 576)) + ret := add(innerTxDataOffset, ret) + } + + function getReservedDynamicBytesLength(innerTxDataOffset) -> ret { + let ptr := getReservedDynamicPtr(innerTxDataOffset) + ret := lengthRoundedByWords(mload(ptr)) + } + + /// This method checks that the transaction's structure is correct + /// and tightly packed + function validateAbiEncoding(txDataOffset) -> ret { + if iszero(eq(mload(txDataOffset), 32)) { + assertionError("Encoding offset") + } + + let innerTxDataOffset := add(txDataOffset, 32) + + let fromValue := getFrom(innerTxDataOffset) + if iszero(validateAddress(fromValue)) { + assertionError("Encoding from") + } + + let toValue := getTo(innerTxDataOffset) + if iszero(validateAddress(toValue)) { + assertionError("Encoding to") + } + + let gasLimitValue := getGasLimit(innerTxDataOffset) + if iszero(validateUint32(gasLimitValue)) { + assertionError("Encoding gasLimit") + } + + let gasPerPubdataByteLimitValue := getGasPerPubdataByteLimit(innerTxDataOffset) + if iszero(validateUint32(gasPerPubdataByteLimitValue)) { + assertionError("Encoding gasPerPubdataByteLimit") + } + + let maxFeePerGas := getMaxFeePerGas(innerTxDataOffset) + if iszero(validateUint128(maxFeePerGas)) { + assertionError("Encoding maxFeePerGas") + } + + let maxPriorityFeePerGas := getMaxPriorityFeePerGas(innerTxDataOffset) + if iszero(validateUint128(maxPriorityFeePerGas)) { + assertionError("Encoding maxPriorityFeePerGas") + } + + let paymasterValue := getPaymaster(innerTxDataOffset) + if iszero(validateAddress(paymasterValue)) { + assertionError("Encoding paymaster") + } + + let expectedDynamicLenPtr := add(innerTxDataOffset, 608) + + let dataLengthPos := getDataPtr(innerTxDataOffset) + if iszero(eq(dataLengthPos, expectedDynamicLenPtr)) { + assertionError("Encoding data") + } + expectedDynamicLenPtr := validateBytes(dataLengthPos) + + let signatureLengthPos := getSignaturePtr(innerTxDataOffset) + if iszero(eq(signatureLengthPos, expectedDynamicLenPtr)) { + assertionError("Encoding signature") + } + expectedDynamicLenPtr := validateBytes(signatureLengthPos) + + let factoryDepsLengthPos := getFactoryDepsPtr(innerTxDataOffset) + if iszero(eq(factoryDepsLengthPos, expectedDynamicLenPtr)) { + assertionError("Encoding factoryDeps") + } + expectedDynamicLenPtr := validateBytes32Array(factoryDepsLengthPos) + + let paymasterInputLengthPos := getPaymasterInputPtr(innerTxDataOffset) + if iszero(eq(paymasterInputLengthPos, expectedDynamicLenPtr)) { + assertionError("Encoding paymasterInput") + } + expectedDynamicLenPtr := validateBytes(paymasterInputLengthPos) + + let reservedDynamicLengthPos := getReservedDynamicPtr(innerTxDataOffset) + if iszero(eq(reservedDynamicLengthPos, expectedDynamicLenPtr)) { + assertionError("Encoding reservedDynamic") + } + expectedDynamicLenPtr := validateBytes(reservedDynamicLengthPos) + + ret := expectedDynamicLenPtr + } + + function getDataLength(innerTxDataOffset) -> ret { + // To get the length of the txData in bytes, we can simply + // get the number of fields * 32 + the length of the dynamic types + // in bytes. + ret := 768 + + ret := safeAdd(ret, getDataBytesLength(innerTxDataOffset), "asx") + ret := safeAdd(ret, getSignatureBytesLength(innerTxDataOffset), "qwqa") + ret := safeAdd(ret, getFactoryDepsBytesLength(innerTxDataOffset), "sic") + ret := safeAdd(ret, getPaymasterInputBytesLength(innerTxDataOffset), "tpiw") + ret := safeAdd(ret, getReservedDynamicBytesLength(innerTxDataOffset), "shy") + } + + /// + /// End of programmatically generated code + /// + + /// @dev Accepts an address and returns whether or not it is + /// a valid address + function validateAddress(addr) -> ret { + ret := lt(addr, shl(160, 1)) + } + + /// @dev Accepts an uint32 and returns whether or not it is + /// a valid uint32 + function validateUint32(x) -> ret { + ret := lt(x, shl(32,1)) + } + + /// @dev Accepts an uint32 and returns whether or not it is + /// a valid uint64 + function validateUint64(x) -> ret { + ret := lt(x, shl(64,1)) + } + + /// @dev Accepts an uint32 and returns whether or not it is + /// a valid uint64 + function validateUint128(x) -> ret { + ret := lt(x, shl(128,1)) + } + + /// Validates that the `bytes` is formed correctly + /// and returns the pointer right after the end of the bytes + function validateBytes(bytesPtr) -> bytesEnd { + let length := mload(bytesPtr) + let lastWordBytes := mod(length, 32) + + switch lastWordBytes + case 0 { + // If the length is divisible by 32, then + // the bytes occupy whole words, so there is + // nothing to validate + bytesEnd := safeAdd(bytesPtr, safeAdd(length, 32, "pol"), "aop") + } + default { + // If the length is not divisible by 32, then + // the last word is padded with zeroes, i.e. + // the last 32 - `lastWordBytes` bytes must be zeroes + // The easiest way to check this is to use AND operator + + let zeroBytes := sub(32, lastWordBytes) + // It has its first 32 - `lastWordBytes` bytes set to 255 + let mask := sub(shl(mul(zeroBytes,8),1),1) + + let fullLen := lengthRoundedByWords(length) + bytesEnd := safeAdd(bytesPtr, safeAdd(32, fullLen, "dza"), "dzp") + + let lastWord := mload(sub(bytesEnd, 32)) + + // If last word contains some unintended bits + // return 0 + if and(lastWord, mask) { + assertionError("bad bytes encoding") + } + } + } + + /// @dev Accepts the pointer to the bytes32[] array length and + /// returns the pointer right after the array's content + function validateBytes32Array(arrayPtr) -> arrayEnd { + // The bytes32[] array takes full words which may contain any content. + // Thus, there is nothing to validate. + let length := mload(arrayPtr) + arrayEnd := safeAdd(arrayPtr, safeAdd(32, safeMul(length, 32, "lop"), "asa"), "sp") + } + + /// + /// Safe math utilities + /// + + /// @dev Returns the multiplication of two unsigned integers, reverting on overflow. + function safeMul(x, y, errMsg) -> ret { + switch y + case 0 { + ret := 0 + } + default { + ret := mul(x, y) + if iszero(eq(div(ret, y), x)) { + assertionError(errMsg) + } + } + } + + /// @dev Returns the integer division of two unsigned integers. Reverts with custom message on + /// division by zero. The result is rounded towards zero. + function safeDiv(x, y, errMsg) -> ret { + if iszero(y) { + assertionError(errMsg) + } + ret := div(x, y) + } + + /// @dev Returns the addition of two unsigned integers, reverting on overflow. + function safeAdd(x, y, errMsg) -> ret { + ret := add(x, y) + if lt(ret, x) { + assertionError(errMsg) + } + } + + /// @dev Returns the subtraction of two unsigned integers, reverting on underflow. + function safeSub(x, y, errMsg) -> ret { + if gt(y, x) { + assertionError(errMsg) + } + ret := sub(x, y) + } + + /// + /// Debug utilities + /// + + /// @dev This method accepts the message and some 1-word data associated with it + /// It triggers a VM hook that allows the server to observe the behavior of the system. + function debugLog(msg, data) { + storeVmHookParam(0, msg) + storeVmHookParam(1, data) + setHook(VM_HOOK_DEBUG_LOG()) + } + + /// @dev Triggers a hook that displays the returndata on the server side. + function debugReturndata() { + debugLog("returndataptr", returnDataPtr()) + storeVmHookParam(0, returnDataPtr()) + setHook(VM_HOOK_DEBUG_RETURNDATA()) + } + + /// @dev Triggers a hook that notifies the operator about the factual number of gas + /// refunded to the user. This is to be used by the operator to derive the correct + /// `gasUsed` in the API. + function notifyAboutRefund(refund) { + storeVmHookParam(0, refund) + setHook(VM_NOTIFY_OPERATOR_ABOUT_FINAL_REFUND()) + debugLog("refund(gas)", refund) + } + + function notifyExecutionResult(success) { + let ptr := returnDataPtr() + storeVmHookParam(0, success) + storeVmHookParam(1, ptr) + setHook(VM_HOOK_EXECUTION_RESULT()) + + debugLog("execution result: success", success) + debugLog("execution result: ptr", ptr) + } + + /// @dev Asks operator for the refund for the transaction. The function provides + /// the operator with the leftover gas found by the bootloader. + /// This function is called before the refund stage, because at that point + /// only the operator knows how close does a transaction + /// bring us to closing the batch as well as how much the transaction + /// should've spent on the pubdata/computation/etc. + /// After it is run, the operator should put the expected refund + /// into the memory slot (in the out of circuit execution). + /// Since the slot after the transaction is not touched, + /// this slot can be used in the in-circuit VM out of box. + function askOperatorForRefund(gasLeft) { + storeVmHookParam(0, gasLeft) + setHook(VM_HOOK_ASK_OPERATOR_FOR_REFUND()) + } + + /// + /// Error codes used for more correct diagnostics from the server side. + /// + + function ETH_CALL_ERR_CODE() -> ret { + ret := 0 + } + + function ACCOUNT_TX_VALIDATION_ERR_CODE() -> ret { + ret := 1 + } + + function FAILED_TO_CHARGE_FEE_ERR_CODE() -> ret { + ret := 2 + } + + function FROM_IS_NOT_AN_ACCOUNT_ERR_CODE() -> ret { + ret := 3 + } + + function FAILED_TO_CHECK_ACCOUNT_ERR_CODE() -> ret { + ret := 4 + } + + function UNACCEPTABLE_GAS_PRICE_ERR_CODE() -> ret { + ret := 5 + } + + function FAILED_TO_SET_NEW_BATCH_ERR_CODE() -> ret { + ret := 6 + } + + function PAY_FOR_TX_FAILED_ERR_CODE() -> ret { + ret := 7 + } + + function PRE_PAYMASTER_PREPARATION_FAILED_ERR_CODE() -> ret { + ret := 8 + } + + function PAYMASTER_VALIDATION_FAILED_ERR_CODE() -> ret { + ret := 9 + } + + function FAILED_TO_SEND_FEES_TO_THE_OPERATOR() -> ret { + ret := 10 + } + + function UNACCEPTABLE_PUBDATA_PRICE_ERR_CODE() -> ret { + ret := 11 + } + + function TX_VALIDATION_FAILED_ERR_CODE() -> ret { + ret := 12 + } + + function MAX_PRIORITY_FEE_PER_GAS_GREATER_THAN_MAX_FEE_PER_GAS() -> ret { + ret := 13 + } + + function BASE_FEE_GREATER_THAN_MAX_FEE_PER_GAS() -> ret { + ret := 14 + } + + function PAYMASTER_RETURNED_INVALID_CONTEXT() -> ret { + ret := 15 + } + + function PAYMASTER_RETURNED_CONTEXT_IS_TOO_LONG() -> ret { + ret := 16 + } + + function ASSERTION_ERROR() -> ret { + ret := 17 + } + + function FAILED_TO_MARK_FACTORY_DEPS() -> ret { + ret := 18 + } + + function TX_VALIDATION_OUT_OF_GAS() -> ret { + ret := 19 + } + + function NOT_ENOUGH_GAS_PROVIDED_ERR_CODE() -> ret { + ret := 20 + } + + function ACCOUNT_RETURNED_INVALID_MAGIC_ERR_CODE() -> ret { + ret := 21 + } + + function PAYMASTER_RETURNED_INVALID_MAGIC_ERR_CODE() -> ret { + ret := 22 + } + + function MINT_ETHER_FAILED_ERR_CODE() -> ret { + ret := 23 + } + + function FAILED_TO_APPEND_TRANSACTION_TO_L2_BLOCK() -> ret { + ret := 24 + } + + function FAILED_TO_SET_L2_BLOCK() -> ret { + ret := 25 + } + + function FAILED_TO_PUBLISH_TIMESTAMP_DATA_TO_L1() -> ret { + ret := 26 + } + + function L1_MESSENGER_PUBLISHING_FAILED_ERR_CODE() -> ret { + ret := 27 + } + + function L1_MESSENGER_LOG_SENDING_FAILED_ERR_CODE() -> ret { + ret := 28 + } + + function FAILED_TO_CALL_SYSTEM_CONTEXT_ERR_CODE() -> ret { + ret := 29 + } + + /// @dev Accepts a 1-word literal and returns its length in bytes + /// @param str A string literal + function getStrLen(str) -> len { + len := 0 + // The string literals are stored left-aligned. Thus, + // In order to get the length of such string, + // we shift it to the left (remove one byte to the left) until + // no more non-empty bytes are left. + for {} str {str := shl(8, str)} { + len := add(len, 1) + } + } + + // Selector of the errors used by the "require" statements in Solidity + // and the one that can be parsed by our server. + function GENERAL_ERROR_SELECTOR() -> ret { + ret := {{REVERT_ERROR_SELECTOR}} + } + + /// @notice Reverts with assertion error with the provided error string literal. + function assertionError(err) { + let ptr := 0 + + // The first byte indicates that the revert reason is an assertion error + mstore8(ptr, ASSERTION_ERROR()) + ptr := add(ptr, 1) + + // Then, we need to put the returndata in a way that is easily parsable by our + // servers + mstore(ptr, GENERAL_ERROR_SELECTOR()) + ptr := add(ptr, 4) + + // Then, goes the "data offset". It is has constant value of 32. + mstore(ptr, 32) + ptr := add(ptr, 32) + + // Then, goes the length of the string: + mstore(ptr, getStrLen(err)) + ptr := add(ptr, 32) + + // Then, we put the actual string + mstore(ptr, err) + ptr := add(ptr, 32) + + revert(0, ptr) + } + + /// @notice Accepts an error code and whether there is a need to copy returndata + /// @param errCode The code of the error + /// @param sendReturnData A flag of whether or not the returndata should be used in the + /// revert reason as well. + function revertWithReason(errCode, sendReturnData) { + let returndataLen := 1 + mstore8(0, errCode) + + if sendReturnData { + // Here we ignore all kinds of limits on the returned data, + // since the `revert` will happen shortly after. + returndataLen := add(returndataLen, returndatasize()) + returndatacopy(1, 0, returndatasize()) + } + revert(0, returndataLen) + } + + /// @notice The id of the VM hook that notifies the operator that the transaction + /// validation rules should start applying (i.e. the user should not be allowed to access + /// other users' storage, etc). + function VM_HOOK_ACCOUNT_VALIDATION_ENTERED() -> ret { + ret := 0 + } + + /// @notice The id of the VM hook that notifies the operator that the transaction + /// paymaster validation has started. + function VM_HOOK_PAYMASTER_VALIDATION_ENTERED() -> ret { + ret := 1 + } + + /// @notice The id of the VM hook that notifies the operator that the transaction's validation + /// restrictions should no longer apply. Note, that this is different from the validation ending, + /// since for instance the bootloader needs to do some actions during validation which are forbidden for users. + /// So this hook is used to notify the operator that the restrictions should be temporarily lifted. + function VM_HOOK_NO_VALIDATION_ENTERED() -> ret { + ret := 2 + } + + /// @notice The id of the VM hook that notifies the operator that the transaction's validation has ended. + function VM_HOOK_VALIDATION_STEP_ENDED() -> ret { + ret := 3 + } + + /// @notice The id of the VM hook that notifies the operator that the transaction's execution has started. + function VM_HOOK_TX_HAS_ENDED() -> ret { + ret := 4 + } + + /// @notice The id of the VM hook that is used to emit debugging logs consisting of pair . + function VM_HOOK_DEBUG_LOG() -> ret { + ret := 5 + } + + /// @notice The id of the VM hook that is used to emit debugging logs with the returndata of the latest transaction. + function VM_HOOK_DEBUG_RETURNDATA() -> ret { + ret := 6 + } + + /// @notice The id of the VM hook that is used to notify the operator about the entry into the + /// `ZKSYNC_CATCH_NEAR_CALL` function. + function VM_HOOK_CATCH_NEAR_CALL() -> ret { + ret := 7 + } + + /// @notice The id of the VM hook that is used to notify the operator about the need to put the refund for + /// the current transaction into the bootloader's memory. + function VM_HOOK_ASK_OPERATOR_FOR_REFUND() -> ret { + ret := 8 + } + + /// @notice The id of the VM hook that is used to notify the operator about the refund given to the user by the bootloader. + function VM_NOTIFY_OPERATOR_ABOUT_FINAL_REFUND() -> ret { + ret := 9 + } + + /// @notice The id of the VM hook that is used to notify the operator about the execution result of the transaction. + function VM_HOOK_EXECUTION_RESULT() -> ret { + ret := 10 + } + + /// @notice The id of the VM hook that is used to notify the operator that it needs to insert the information about the last + /// fictive miniblock. + function VM_HOOK_FINAL_L2_STATE_INFO() -> ret { + ret := 11 + } + + /// @norice The id of the VM hook that use used to notify the operator that it needs to insert the pubdata. + function VM_HOOK_PUBDATA_REQUESTED() -> ret { + ret := 12 + } + + // Need to prevent the compiler from optimizing out similar operations, + // which may have different meaning for the offline debugging + function $llvm_NoInline_llvm$_unoptimized(val) -> ret { + ret := add(val, callvalue()) + } + + /// @notice Triggers a VM hook. + /// The server will recognize it and output corresponding logs. + function setHook(hook) { + mstore(VM_HOOK_PTR(), $llvm_NoInline_llvm$_unoptimized(hook)) + } + + /// @notice Sets a value to a param of the vm hook. + /// @param paramId The id of the VmHook parameter. + /// @param value The value of the parameter. + /// @dev This method should be called before triggering the VM hook itself. + /// @dev It is the responsibility of the caller to never provide + /// paramId smaller than the VM_HOOK_PARAMS() + function storeVmHookParam(paramId, value) { + let offset := add(VM_HOOK_PARAMS_OFFSET(), mul(32, paramId)) + mstore(offset, $llvm_NoInline_llvm$_unoptimized(value)) + } + + /// @dev Log key used by Executor.sol for processing. See Constants.sol::SystemLogKey enum + function chainedPriorityTxnHashLogKey() -> ret { + ret := 5 + } + + /// @dev Log key used by Executor.sol for processing. See Constants.sol::SystemLogKey enum + function numberOfLayer1TxsLogKey() -> ret { + ret := 6 + } + + /// @dev Log key used by Executor.sol for processing. See Constants.sol::SystemLogKey enum + function protocolUpgradeTxHashKey() -> ret { + ret := 7 + } + + //////////////////////////////////////////////////////////////////////////// + // Main Transaction Processing + //////////////////////////////////////////////////////////////////////////// + + /// @notice the address that will be the beneficiary of all the fees + let OPERATOR_ADDRESS := mload(0) + + let GAS_PRICE_PER_PUBDATA := 0 + + // Initializing block params + { + /// @notice The hash of the previous batch + let PREV_BATCH_HASH := mload(32) + /// @notice The timestamp of the batch being processed + let NEW_BATCH_TIMESTAMP := mload(64) + /// @notice The number of the new batch being processed. + /// While this number is deterministic for each batch, we + /// still provide it here to ensure consistency between the state + /// of the VM and the state of the operator. + let NEW_BATCH_NUMBER := mload(96) + + /// @notice The gas price on L1 for ETH. In the future, a trustless value will be enforced. + /// For now, this value is trusted to be fairly provided by the operator. + let L1_GAS_PRICE := mload(128) + + /// @notice The minimal gas price that the operator agrees upon. + /// In the future, it will have an EIP1559-like lower bound. + let FAIR_L2_GAS_PRICE := mload(160) + + /// @notice The expected base fee by the operator. + /// Just like the batch number, while calculated on the bootloader side, + /// the operator still provides it to make sure that its data is in sync. + let EXPECTED_BASE_FEE := mload(192) + + validateOperatorProvidedPrices(L1_GAS_PRICE, FAIR_L2_GAS_PRICE) + + let baseFee := 0 + + + + // This implementation of the bootloader relies on the correct version of the SystemContext + // and it can not be upgraded via a standard upgrade transaction, but needs to ensure + // correctness itself before any transaction is executed. + upgradeSystemContextIfNeeded() + + // Only for the proved batch we enforce that the baseFee proposed + // by the operator is equal to the expected one. For the playground batch, we allow + // the operator to provide any baseFee the operator wants. + baseFee, GAS_PRICE_PER_PUBDATA := getBaseFee(L1_GAS_PRICE, FAIR_L2_GAS_PRICE) + if iszero(eq(baseFee, EXPECTED_BASE_FEE)) { + debugLog("baseFee", baseFee) + debugLog("EXPECTED_BASE_FEE", EXPECTED_BASE_FEE) + assertionError("baseFee inconsistent") + } + + setNewBatch(PREV_BATCH_HASH, NEW_BATCH_TIMESTAMP, NEW_BATCH_NUMBER, EXPECTED_BASE_FEE) + + + + + + baseFee, GAS_PRICE_PER_PUBDATA := getBaseFee(L1_GAS_PRICE, FAIR_L2_GAS_PRICE) + + let SHOULD_SET_NEW_BATCH := mload(224) + + upgradeSystemContextIfNeeded() + + switch SHOULD_SET_NEW_BATCH + case 0 { + unsafeOverrideBatch(NEW_BATCH_TIMESTAMP, NEW_BATCH_NUMBER, EXPECTED_BASE_FEE) + } + default { + setNewBatch(PREV_BATCH_HASH, NEW_BATCH_TIMESTAMP, NEW_BATCH_NUMBER, EXPECTED_BASE_FEE) + } + + + } + + // Now, we iterate over all transactions, processing each of them + // one by one. + // Here, the `resultPtr` is the pointer to the memory slot, where we will write + // `true` or `false` based on whether the tx execution was successful, + + // The position at which the tx offset of the transaction should be placed + let currentExpectedTxOffset := add(TXS_IN_BATCH_LAST_PTR(), mul(MAX_POSTOP_SLOTS(), 32)) + + let txPtr := TX_DESCRIPTION_BEGIN_BYTE() + + // At the COMPRESSED_BYTECODES_BEGIN_BYTE() the pointer to the newest bytecode to be published + // is stored. + mstore(COMPRESSED_BYTECODES_BEGIN_BYTE(), add(COMPRESSED_BYTECODES_BEGIN_BYTE(), 32)) + + // At start storing keccak256("") as `chainedPriorityTxsHash` and 0 as `numberOfLayer1Txs` + mstore(PRIORITY_TXS_L1_DATA_BEGIN_BYTE(), EMPTY_STRING_KECCAK()) + mstore(add(PRIORITY_TXS_L1_DATA_BEGIN_BYTE(), 32), 0) + + // Iterating through transaction descriptions + let transactionIndex := 0 + for { + let resultPtr := RESULT_START_PTR() + } lt(txPtr, TXS_IN_BATCH_LAST_PTR()) { + txPtr := add(txPtr, TX_DESCRIPTION_SIZE()) + resultPtr := add(resultPtr, 32) + transactionIndex := add(transactionIndex, 1) + } { + let execute := mload(txPtr) + + debugLog("txPtr", txPtr) + debugLog("execute", execute) + + if iszero(execute) { + // We expect that all transactions that are executed + // are continuous in the array. + break + } + + let txDataOffset := mload(add(txPtr, 32)) + + // We strongly enforce the positions of transactions + if iszero(eq(currentExpectedTxOffset, txDataOffset)) { + debugLog("currentExpectedTxOffset", currentExpectedTxOffset) + debugLog("txDataOffset", txDataOffset) + + assertionError("Tx data offset is incorrect") + } + + currentExpectedTxOffset := validateAbiEncoding(txDataOffset) + + // Checking whether the last slot of the transaction's description + // does not go out of bounds. + if gt(sub(currentExpectedTxOffset, 32), LAST_FREE_SLOT()) { + debugLog("currentExpectedTxOffset", currentExpectedTxOffset) + debugLog("LAST_FREE_SLOT", LAST_FREE_SLOT()) + + assertionError("currentExpectedTxOffset too high") + } + + validateTypedTxStructure(add(txDataOffset, 32)) + + + { + debugLog("ethCall", 0) + processTx(txDataOffset, resultPtr, transactionIndex, 0, GAS_PRICE_PER_PUBDATA) + } + + + { + let txMeta := mload(txPtr) + let processFlags := getWordByte(txMeta, 31) + debugLog("flags", processFlags) + + + // `processFlags` argument denotes which parts of execution should be done: + // Possible values: + // 0x00: validate & execute (normal mode) + // 0x02: perform ethCall (i.e. use mimicCall to simulate the call) + + let isETHCall := eq(processFlags, 0x02) + debugLog("ethCall", isETHCall) + processTx(txDataOffset, resultPtr, transactionIndex, isETHCall, GAS_PRICE_PER_PUBDATA) + } + + // Signal to the vm that the transaction execution is complete + setHook(VM_HOOK_TX_HAS_ENDED()) + // Increment tx index within the system. + considerNewTx() + } + + // The bootloader doesn't have to pay anything + setPricePerPubdataByte(0) + + // Resetting tx.origin and gasPrice to 0, so we don't pay for + // publishing them on-chain. + setTxOrigin(0) + setGasPrice(0) + + // Transfering all the ETH received in the block to the operator + directETHTransfer( + selfbalance(), + OPERATOR_ADDRESS + ) + + // Hook that notifies that the operator should provide final information for the batch + setHook(VM_HOOK_FINAL_L2_STATE_INFO()) + + // Each batch typically ends with a special block which contains no transactions. + // So we need to have this method to reflect it in the system contracts too. + // + // The reason is that as of now our node requires that each storage write (event, etc) belongs to a particular + // L2 block. In case a batch is sealed by timeout (i.e. the resources of the batch have not been exhaused, but we need + // to seal it to assure timely finality), we need to process sending funds to the operator *after* the last + // non-empty L2 block has been already sealed. We can not override old L2 blocks, so we need to create a new empty "fictive" block for it. + // + // The other reason why we need to set this block is so that in case of empty batch (i.e. the one which has no transactions), + // the virtual block number as well as miniblock number are incremented. + setL2Block(transactionIndex) + + callSystemContext({{RIGHT_PADDED_RESET_TX_NUMBER_IN_BLOCK_SELECTOR}}) + + publishTimestampDataToL1() + + // Sending system logs (to be processed on L1) + sendToL1Native(true, chainedPriorityTxnHashLogKey(), mload(PRIORITY_TXS_L1_DATA_BEGIN_BYTE())) + sendToL1Native(true, numberOfLayer1TxsLogKey(), mload(add(PRIORITY_TXS_L1_DATA_BEGIN_BYTE(), 32))) + + l1MessengerPublishingCall() + } + } +} diff --git a/system-contracts/bootloader/test_infra/Cargo.lock b/system-contracts/bootloader/test_infra/Cargo.lock new file mode 100644 index 000000000..bc2ea88e8 --- /dev/null +++ b/system-contracts/bootloader/test_infra/Cargo.lock @@ -0,0 +1,6169 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addchain" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +dependencies = [ + "num-bigint 0.3.3", + "num-integer", + "num-traits", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" +dependencies = [ + "aes-soft", + "aesni", + "cipher", +] + +[[package]] +name = "aes-ctr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7729c3cde54d67063be556aeac75a81330d802f0259500ca40cb52967f975763" +dependencies = [ + "aes-soft", + "aesni", + "cipher", + "ctr", +] + +[[package]] +name = "aes-soft" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" +dependencies = [ + "cipher", + "opaque-debug", +] + +[[package]] +name = "aesni" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +dependencies = [ + "cipher", + "opaque-debug", +] + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom 0.2.11", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "arr_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a105bfda48707cf19220129e78fca01e9639433ffaef4163546ed8fb04120a5" +dependencies = [ + "arr_macro_impl", + "proc-macro-hack", +] + +[[package]] +name = "arr_macro_impl" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0609c78bd572f4edc74310dfb63a01f5609d53fa8b4dd7c4d98aef3b3e8d72d1" +dependencies = [ + "proc-macro-hack", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.1.0", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "bellman_ce" +version = "0.3.2" +source = "git+https://github.com/matter-labs/bellman?branch=dev#5520aa2274afe73d281373c92b007a2ecdebfbea" +dependencies = [ + "arrayvec 0.7.4", + "bit-vec", + "blake2s_const", + "blake2s_simd", + "byteorder", + "cfg-if 1.0.0", + "crossbeam 0.7.3", + "futures", + "hex", + "lazy_static", + "num_cpus", + "pairing_ce 0.28.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6", + "serde", + "smallvec", + "tiny-keccak 1.5.0", +] + +[[package]] +name = "bigdecimal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1e50562e37200edf7c6c43e54a08e64a5553bfb59d9c297d5572512aa517256" +dependencies = [ + "num-bigint 0.3.3", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease", + "proc-macro2 1.0.70", + "quote 1.0.33", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.40", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty 1.1.0", + "radium 0.6.2", + "tap", + "wyz 0.2.0", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty 2.0.0", + "radium 0.7.0", + "tap", + "wyz 0.5.1", +] + +[[package]] +name = "blake2" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e#1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2-rfc_bellman_edition" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc60350286c7c3db13b98e91dbe5c8b6830a6821bc20af5b0c310ce94d74915" +dependencies = [ + "arrayvec 0.4.12", + "byteorder", + "constant_time_eq", +] + +[[package]] +name = "blake2s_const" +version = "0.6.0" +source = "git+https://github.com/matter-labs/bellman?branch=dev#5520aa2274afe73d281373c92b007a2ecdebfbea" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-modes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +dependencies = [ + "block-padding", + "cipher", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytecount" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.5", +] + +[[package]] +name = "cipher" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +dependencies = [ + "generic-array", +] + +[[package]] +name = "circuit_testing" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-circuit_testing.git?branch=main#164c0adac85be39ee44bd9456b2b91cdede5af80" +dependencies = [ + "bellman_ce", +] + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "codegen" +version = "0.1.0" +source = "git+https://github.com/matter-labs/solidity_plonk_verifier.git?branch=dev#82f96b7156551087f1c9bfe4f0ea68845b6debfc" +dependencies = [ + "ethereum-types 0.14.1", + "franklin-crypto", + "handlebars", + "hex", + "paste", + "rescue_poseidon", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "codegen" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff61280aed771c3070e7dcc9e050c66f1eb1e3b96431ba66f9f74641d02fc41d" +dependencies = [ + "indexmap 1.9.3", +] + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crossbeam" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-channel 0.4.4", + "crossbeam-deque 0.7.4", + "crossbeam-epoch 0.8.2", + "crossbeam-queue 0.2.3", + "crossbeam-utils 0.7.2", +] + +[[package]] +name = "crossbeam" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-channel 0.5.8", + "crossbeam-deque 0.8.3", + "crossbeam-epoch 0.9.15", + "crossbeam-queue 0.3.8", + "crossbeam-utils 0.8.16", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils 0.8.16", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" +dependencies = [ + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch 0.9.15", + "crossbeam-utils 0.8.16", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg 1.1.0", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "lazy_static", + "maybe-uninit", + "memoffset 0.5.6", + "scopeguard", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg 1.1.0", + "cfg-if 1.0.0", + "crossbeam-utils 0.8.16", + "memoffset 0.9.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils 0.8.16", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg 1.1.0", + "cfg-if 0.1.10", + "lazy_static", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "cs_derive" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-sync_vm.git?branch=v1.3.3#ed8ab8984cae05d00d9d62196753c8d40df47c7d" +dependencies = [ + "proc-macro-error", + "proc-macro2 1.0.70", + "quote 1.0.33", + "serde", + "syn 1.0.109", +] + +[[package]] +name = "ctr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.70", + "quote 1.0.33", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2 1.0.70", + "quote 1.0.33", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve", + "rfc6979", + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.2.0", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der 0.6.1", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "elsa" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714f766f3556b44e7e4776ad133fcc3445a489517c25c704ace411bb14790194" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "envy" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965" +dependencies = [ + "serde", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types 0.14.1", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb684ac8fa8f6c5759f788862bb22ec6fe3cb392f6bfd08e3c64b603661e3f8" +dependencies = [ + "crunchy", + "fixed-hash 0.7.0", + "impl-rlp", + "impl-serde 0.3.2", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash 0.8.0", + "impl-rlp", + "impl-serde 0.4.0", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethereum-types" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05136f7057fe789f06e6d41d07b34e6f70d8c86e5693b60f97aaa6553553bdaf" +dependencies = [ + "ethbloom 0.11.1", + "fixed-hash 0.7.0", + "impl-rlp", + "impl-serde 0.3.2", + "primitive-types 0.10.1", + "uint", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom 0.13.0", + "fixed-hash 0.8.0", + "impl-rlp", + "impl-serde 0.4.0", + "primitive-types 0.12.2", + "uint", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff_ce" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b538e4231443a5b9c507caee3356f016d832cf7393d2d90f03ea3180d4e3fbc" +dependencies = [ + "byteorder", + "ff_derive_ce", + "hex", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "ff_derive_ce" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96fbccd88dbb1fac4ee4a07c2fcc4ca719a74ffbd9d2b9d41d8c8eb073d8b20" +dependencies = [ + "num-bigint 0.4.4", + "num-integer", + "num-traits", + "proc-macro2 1.0.70", + "quote 1.0.33", + "serde", + "syn 1.0.109", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "franklin-crypto" +version = "0.0.5" +source = "git+https://github.com/matter-labs/franklin-crypto?branch=dev#5695d07c7bc604c2c39a27712ffac171d39ee1ed" +dependencies = [ + "arr_macro", + "bellman_ce", + "bit-vec", + "blake2 0.9.2", + "blake2-rfc_bellman_edition", + "blake2s_simd", + "byteorder", + "digest 0.9.0", + "hex", + "indexmap 1.9.3", + "itertools 0.10.5", + "lazy_static", + "num-bigint 0.4.4", + "num-derive 0.2.5", + "num-integer", + "num-traits", + "rand 0.4.6", + "serde", + "sha2 0.9.9", + "sha3 0.9.1", + "smallvec", + "splitmut", + "tiny-keccak 1.5.0", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "handlebars" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.5", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec 2.3.1", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec 3.6.9", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg 1.1.0", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "ipnetwork" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c3eaab3ac0ede60ffa41add21970a7df7d91772c03383aac6c2c3d53cc716b" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi 0.3.3", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa", + "elliptic-curve", + "sha2 0.10.8", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", +] + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linkme" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e6b0bb9ca88d3c5ae88240beb9683821f903b824ee8381ef9ab4e8522fbfa9" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b3f61e557a617ec6ba36c79431e1f3b5e100d67cfbdb61ed6ef384298af016" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg 1.1.0", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "logos" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +dependencies = [ + "beef", + "fnv", + "proc-macro2 1.0.70", + "quote 1.0.33", + "regex-syntax 0.6.29", + "syn 2.0.40", +] + +[[package]] +name = "logos-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if 1.0.0", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg 1.1.0", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg 1.1.0", +] + +[[package]] +name = "metrics" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" +dependencies = [ + "ahash 0.8.6", + "metrics-macros", + "portable-atomic", +] + +[[package]] +name = "metrics-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mini-moka" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e0b72e7c9042467008b10279fc732326bd605459ae03bda88825909dd19b56" +dependencies = [ + "crossbeam-channel 0.5.8", + "crossbeam-utils 0.8.16", + "dashmap", + "skeptic", + "smallvec", + "tagptr", + "triomphe", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "multivm" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "anyhow", + "hex", + "itertools 0.10.5", + "once_cell", + "thiserror", + "tracing", + "vise", + "zk_evm 1.3.1", + "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2)", + "zk_evm 1.4.0", + "zksync_contracts", + "zksync_state", + "zksync_system_constants", + "zksync_types", + "zksync_utils", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" +dependencies = [ + "num-bigint 0.3.3", + "num-complex 0.3.1", + "num-integer", + "num-iter", + "num-rational 0.3.2", + "num-traits", +] + +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint 0.4.4", + "num-complex 0.4.4", + "num-integer", + "num-iter", + "num-rational 0.4.1", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg 1.1.0", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg 1.1.0", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg 1.1.0", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg 1.1.0", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg 1.1.0", + "num-bigint 0.3.3", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg 1.1.0", + "num-bigint 0.4.4", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg 1.1.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.3", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +dependencies = [ + "bitflags 2.4.1", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "os_info" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +dependencies = [ + "log", + "serde", + "winapi", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pairing_ce" +version = "0.28.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db007b21259660d025918e653508f03050bf23fb96a88601f9936329faadc597" +dependencies = [ + "byteorder", + "cfg-if 1.0.0", + "ff_ce", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "pairing_ce" +version = "0.28.5" +source = "git+https://github.com/matter-labs/pairing.git?rev=f55393f#f55393fd366596eac792d78525d26e9c4d6ed1ca" +dependencies = [ + "byteorder", + "cfg-if 1.0.0", + "ff_ce", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "parity-crypto" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b92ea9ddac0d6e1db7c49991e7d397d34a9fd814b4c93cda53788e8eef94e35" +dependencies = [ + "aes", + "aes-ctr", + "block-modes", + "digest 0.9.0", + "ethereum-types 0.12.1", + "hmac 0.10.1", + "lazy_static", + "pbkdf2 0.7.5", + "ripemd160", + "rustc-hex", + "scrypt", + "secp256k1 0.20.3", + "sha2 0.9.9", + "subtle", + "tiny-keccak 2.0.2", + "zeroize", +] + +[[package]] +name = "parity-scale-codec" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +dependencies = [ + "arrayvec 0.7.4", + "bitvec 0.20.4", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive 2.3.1", + "serde", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec 0.7.4", + "bitvec 1.0.1", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive 3.6.9", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.1", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "password-hash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54986aa4bfc9b98c6a5f40184223658d187159d7b3c6af33f2b2aa25ae1db0fa" +dependencies = [ + "base64ct", + "rand_core 0.6.4", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b8c0d71734018084da0c0354193a5edfb81b20d2d57a92c5b154aefc554a4a" +dependencies = [ + "crypto-mac 0.10.1", +] + +[[package]] +name = "pbkdf2" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf916dd32dd26297907890d99dc2740e33f6bd9073965af4ccff2967962f5508" +dependencies = [ + "base64ct", + "crypto-mac 0.10.1", + "hmac 0.10.1", + "password-hash", + "sha2 0.9.9", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "pest_meta" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.3", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "platforms" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2 1.0.70", + "syn 2.0.40", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "impl-codec 0.5.1", + "impl-rlp", + "impl-serde 0.3.2", + "uint", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "impl-rlp", + "impl-serde 0.4.0", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus-client" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c99afa9a01501019ac3a14d71d9f94050346f55ca471ce90c799a15c58f61e2" +dependencies = [ + "dtoa", + "itoa", + "parking_lot 0.12.1", + "prometheus-client-derive-encode", +] + +[[package]] +name = "prometheus-client-derive-encode" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.11.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.40", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "prost-reflect" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057237efdb71cf4b3f9396302a3d6599a92fa94063ba537b66130980ea9909f3" +dependencies = [ + "base64 0.21.5", + "logos", + "miette", + "once_cell", + "prost", + "prost-types", + "serde", + "serde-value", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + +[[package]] +name = "protox" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bb76c5f6221de491fe2c8f39b106330bbd9762c6511119c07940e10eb9ff11" +dependencies = [ + "bytes", + "miette", + "prost", + "prost-reflect", + "prost-types", + "protox-parse", + "thiserror", +] + +[[package]] +name = "protox-parse" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4581f441c58863525a3e6bec7b8de98188cf75239a56c725a3e7288450a33f" +dependencies = [ + "logos", + "miette", + "prost-types", + "thiserror", +] + +[[package]] +name = "pulldown-cmark" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2 1.0.70", +] + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.8", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.11", +] + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque 0.8.3", + "crossbeam-utils 0.8.16", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.11", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "rescue_poseidon" +version = "0.4.1" +source = "git+https://github.com/matter-labs/rescue-poseidon#d059b5042df5ed80e151f05751410b524a54d16c" +dependencies = [ + "addchain", + "arrayvec 0.7.4", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "franklin-crypto", + "num-bigint 0.3.3", + "num-integer", + "num-iter", + "num-traits", + "rand 0.4.6", + "serde", + "sha3 0.9.1", + "smallvec", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac 0.12.1", + "zeroize", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom 0.2.11", + "libc", + "spin", + "untrusted", + "windows-sys 0.48.0", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "salsa20" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399f290ffc409596022fce5ea5d4138184be4784f2b28c62c59f0d8389059a15" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da492dab03f925d977776a0b7233d7b934d6dc2b94faead48928e2e9bacedb9" +dependencies = [ + "base64 0.13.1", + "hmac 0.10.1", + "pbkdf2 0.6.0", + "rand 0.7.3", + "rand_core 0.5.1", + "salsa20", + "sha2 0.9.9", + "subtle", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "rand 0.6.5", + "secp256k1-sys 0.4.2", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "secp256k1-sys 0.8.1", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] + +[[package]] +name = "sentry" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce4b57f1b521f674df7a1d200be8ff5d74e3712020ee25b553146657b5377d5" +dependencies = [ + "httpdate", + "native-tls", + "reqwest", + "sentry-backtrace", + "sentry-contexts", + "sentry-core", + "sentry-debug-images", + "sentry-panic", + "sentry-tracing", + "tokio", + "ureq", +] + +[[package]] +name = "sentry-backtrace" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cc8d4e04a73de8f718dc703943666d03f25d3e9e4d0fb271ca0b8c76dfa00e" +dependencies = [ + "backtrace", + "once_cell", + "regex", + "sentry-core", +] + +[[package]] +name = "sentry-contexts" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6436c1bad22cdeb02179ea8ef116ffc217797c028927def303bc593d9320c0d1" +dependencies = [ + "hostname", + "libc", + "os_info", + "rustc_version", + "sentry-core", + "uname", +] + +[[package]] +name = "sentry-core" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901f761681f97db3db836ef9e094acdd8756c40215326c194201941947164ef1" +dependencies = [ + "once_cell", + "rand 0.8.5", + "sentry-types", + "serde", + "serde_json", +] + +[[package]] +name = "sentry-debug-images" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afdb263e73d22f39946f6022ed455b7561b22ff5553aca9be3c6a047fa39c328" +dependencies = [ + "findshlibs", + "once_cell", + "sentry-core", +] + +[[package]] +name = "sentry-panic" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fbf1c163f8b6a9d05912e1b272afa27c652e8b47ea60cb9a57ad5e481eea99" +dependencies = [ + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-tracing" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82eabcab0a047040befd44599a1da73d3adb228ff53b5ed9795ae04535577704" +dependencies = [ + "sentry-backtrace", + "sentry-core", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sentry-types" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da956cca56e0101998c8688bc65ce1a96f00673a0e58e663664023d4c7911e82" +dependencies = [ + "debugid", + "hex", + "rand 0.8.5", + "serde", + "serde_json", + "thiserror", + "time", + "url", + "uuid", +] + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +dependencies = [ + "base64 0.13.1", + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +dependencies = [ + "darling", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=1731ced4a116d61ba9dc6ee6d0f38fb8102e357a#1731ced4a116d61ba9dc6ee6d0f38fb8102e357a" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=7a187e934c1f6c68e4b4e5cf37541b7a0d64d303#7a187e934c1f6c68e4b4e5cf37541b7a0d64d303" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "skeptic" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" +dependencies = [ + "bytecount", + "cargo_metadata", + "error-chain", + "glob", + "pulldown-cmark", + "tempfile", + "walkdir", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg 1.1.0", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.8", +] + +[[package]] +name = "splitmut" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85070f382340e8b23a75808e83573ddf65f9ad9143df9573ca37c1ed2ee956a" + +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools 0.10.5", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" +dependencies = [ + "ahash 0.7.7", + "atoi", + "base64 0.13.1", + "bigdecimal", + "bitflags 1.3.2", + "byteorder", + "bytes", + "chrono", + "crc", + "crossbeam-queue 0.3.8", + "dirs", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "hkdf", + "hmac 0.12.1", + "indexmap 1.9.3", + "ipnetwork", + "itoa", + "libc", + "log", + "md-5", + "memchr", + "num-bigint 0.3.3", + "once_cell", + "paste", + "percent-encoding", + "rand 0.8.5", + "serde", + "serde_json", + "sha-1", + "sha2 0.10.8", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "whoami", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" +dependencies = [ + "dotenv", + "either", + "heck 0.4.1", + "hex", + "once_cell", + "proc-macro2 1.0.70", + "quote 1.0.33", + "serde", + "serde_json", + "sha2 0.10.8", + "sqlx-core", + "sqlx-rt", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" +dependencies = [ + "native-tls", + "once_cell", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.70", + "quote 1.0.33", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "sync_vm" +version = "1.3.3" +source = "git+https://github.com/matter-labs/era-sync_vm.git?branch=v1.3.3#ed8ab8984cae05d00d9d62196753c8d40df47c7d" +dependencies = [ + "arrayvec 0.7.4", + "cs_derive", + "derivative", + "franklin-crypto", + "hex", + "itertools 0.10.5", + "num-bigint 0.4.4", + "num-derive 0.3.3", + "num-integer", + "num-traits", + "once_cell", + "rand 0.4.6", + "rescue_poseidon", + "serde", + "smallvec", + "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.3.3)", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "termcolor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test-log" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6159ab4116165c99fc88cce31f99fa2c9dbe08d3691cb38da02fc3b45f357d2b" +dependencies = [ + "env_logger 0.10.1", + "test-log-macros", +] + +[[package]] +name = "test-log-macros" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba277e77219e9eea169e8508942db1bf5d8a41ff2db9b20aab5a5aadc9fa25d" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "test_infra" +version = "0.1.0" +dependencies = [ + "colored", + "hex", + "multivm", + "once_cell", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", + "vlog", + "zksync_contracts", + "zksync_state", + "zksync_types", + "zksync_utils", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "time", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" +dependencies = [ + "base64 0.21.5", + "log", + "native-tls", + "once_cell", + "url", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", + "serde", +] + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vise" +version = "0.1.0" +source = "git+https://github.com/matter-labs/vise.git?rev=dd05139b76ab0843443ab3ff730174942c825dae#dd05139b76ab0843443ab3ff730174942c825dae" +dependencies = [ + "elsa", + "linkme", + "once_cell", + "prometheus-client", + "vise-macros", +] + +[[package]] +name = "vise-macros" +version = "0.1.0" +source = "git+https://github.com/matter-labs/vise.git?rev=dd05139b76ab0843443ab3ff730174942c825dae#dd05139b76ab0843443ab3ff730174942c825dae" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "vlog" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "chrono", + "sentry", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote 1.0.33", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[package]] +name = "web-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web3" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5388522c899d1e1c96a4c307e3797e0f697ba7c77dd8e0e625ecba9dd0342937" +dependencies = [ + "arrayvec 0.7.4", + "base64 0.21.5", + "bytes", + "derive_more", + "ethabi", + "ethereum-types 0.14.1", + "futures", + "futures-timer", + "headers", + "hex", + "idna 0.4.0", + "jsonrpc-core", + "log", + "once_cell", + "parking_lot 0.12.1", + "pin-project", + "reqwest", + "rlp", + "secp256k1 0.27.0", + "serde", + "serde_json", + "tiny-keccak 2.0.2", + "url", +] + +[[package]] +name = "webpki-roots" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2 1.0.70", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "zk_evm" +version = "1.3.1" +source = "git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.1-rc2#0a7c775932db4839ff6b7fb0db9bdb3583ab54c0" +dependencies = [ + "blake2 0.10.6 (git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e)", + "k256", + "lazy_static", + "num 0.4.1", + "serde", + "serde_json", + "sha2 0.10.6", + "sha3 0.10.6", + "static_assertions", + "zkevm_opcode_defs 1.3.1", +] + +[[package]] +name = "zk_evm" +version = "1.3.3" +source = "git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2#fbee20f5bac7d6ca3e22ae69b2077c510a07de4e" +dependencies = [ + "anyhow", + "lazy_static", + "num 0.4.1", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm" +version = "1.3.3" +source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.3.3#fbee20f5bac7d6ca3e22ae69b2077c510a07de4e" +dependencies = [ + "anyhow", + "lazy_static", + "num 0.4.1", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm" +version = "1.4.0" +source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.4.0#dd76fc5badf2c05278a21b38015a7798fe2fe358" +dependencies = [ + "anyhow", + "lazy_static", + "num 0.4.1", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm_abstractions" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git#15a2af404902d5f10352e3d1fac693cc395fcff9" +dependencies = [ + "anyhow", + "serde", + "static_assertions", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zkevm-assembly" +version = "1.3.2" +source = "git+https://github.com/matter-labs/era-zkEVM-assembly.git?branch=v1.3.2#3c61d450cbe6548068be8f313ed02f1bd229a865" +dependencies = [ + "env_logger 0.9.3", + "hex", + "lazy_static", + "log", + "nom", + "num-bigint 0.4.4", + "num-traits", + "sha3 0.10.8", + "smallvec", + "structopt", + "thiserror", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zkevm_opcode_defs" +version = "1.3.1" +source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.3.1#00d4ad2292bd55374a0fa10fe11686d7a109d8a0" +dependencies = [ + "bitflags 1.3.2", + "ethereum-types 0.14.1", + "lazy_static", + "sha2 0.10.8", +] + +[[package]] +name = "zkevm_opcode_defs" +version = "1.3.2" +source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.3.2#dffacadeccdfdbff4bc124d44c595c4a6eae5013" +dependencies = [ + "bitflags 2.4.1", + "blake2 0.10.6 (git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e)", + "ethereum-types 0.14.1", + "k256", + "lazy_static", + "sha2 0.10.6", + "sha3 0.10.6", +] + +[[package]] +name = "zkevm_test_harness" +version = "1.3.3" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.3.3#d52b56d6ba8196c8a3c74c4933654469e6f27a5a" +dependencies = [ + "bincode", + "circuit_testing", + "codegen 0.2.0", + "crossbeam 0.8.2", + "derivative", + "env_logger 0.10.1", + "hex", + "num-bigint 0.4.4", + "num-integer", + "num-traits", + "rayon", + "serde", + "serde_json", + "smallvec", + "structopt", + "sync_vm", + "test-log", + "tracing", + "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.3.3)", + "zkevm-assembly", +] + +[[package]] +name = "zksync_basic_types" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "serde", + "serde_json", + "web3", +] + +[[package]] +name = "zksync_concurrency" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=da015d4c94b19962bc11622b6cc256e214256555#da015d4c94b19962bc11622b6cc256e214256555" +dependencies = [ + "anyhow", + "once_cell", + "pin-project", + "rand 0.8.5", + "sha3 0.10.8", + "thiserror", + "time", + "tokio", + "tracing", + "tracing-subscriber", + "vise", +] + +[[package]] +name = "zksync_consensus_crypto" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=da015d4c94b19962bc11622b6cc256e214256555#da015d4c94b19962bc11622b6cc256e214256555" +dependencies = [ + "anyhow", + "blst", + "ed25519-dalek", + "ff_ce", + "hex", + "pairing_ce 0.28.5 (git+https://github.com/matter-labs/pairing.git?rev=f55393f)", + "rand 0.4.6", + "rand 0.8.5", + "sha3 0.10.8", + "thiserror", + "tracing", +] + +[[package]] +name = "zksync_consensus_roles" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=da015d4c94b19962bc11622b6cc256e214256555#da015d4c94b19962bc11622b6cc256e214256555" +dependencies = [ + "anyhow", + "bit-vec", + "hex", + "prost", + "rand 0.8.5", + "serde", + "thiserror", + "tracing", + "zksync_concurrency", + "zksync_consensus_crypto", + "zksync_consensus_utils", + "zksync_protobuf", + "zksync_protobuf_build", +] + +[[package]] +name = "zksync_consensus_utils" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=da015d4c94b19962bc11622b6cc256e214256555#da015d4c94b19962bc11622b6cc256e214256555" +dependencies = [ + "thiserror", + "zksync_concurrency", +] + +[[package]] +name = "zksync_contracts" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "envy", + "ethabi", + "hex", + "once_cell", + "serde", + "serde_json", + "zksync_utils", +] + +[[package]] +name = "zksync_crypto" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "base64 0.13.1", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "once_cell", + "serde", + "sha2 0.9.9", + "thiserror", + "zksync_basic_types", +] + +[[package]] +name = "zksync_dal" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "anyhow", + "bigdecimal", + "bincode", + "hex", + "itertools 0.10.5", + "num 0.3.1", + "once_cell", + "prost", + "rand 0.8.5", + "serde", + "serde_json", + "sqlx", + "strum", + "thiserror", + "tokio", + "tracing", + "url", + "vise", + "zksync_consensus_roles", + "zksync_contracts", + "zksync_health_check", + "zksync_protobuf", + "zksync_protobuf_build", + "zksync_system_constants", + "zksync_types", + "zksync_utils", +] + +[[package]] +name = "zksync_health_check" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "async-trait", + "futures", + "serde", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "zksync_mini_merkle_tree" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "once_cell", + "zksync_basic_types", + "zksync_crypto", +] + +[[package]] +name = "zksync_protobuf" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=da015d4c94b19962bc11622b6cc256e214256555#da015d4c94b19962bc11622b6cc256e214256555" +dependencies = [ + "anyhow", + "bit-vec", + "once_cell", + "prost", + "prost-reflect", + "quick-protobuf", + "rand 0.8.5", + "serde", + "serde_json", + "zksync_concurrency", + "zksync_protobuf_build", +] + +[[package]] +name = "zksync_protobuf_build" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=da015d4c94b19962bc11622b6cc256e214256555#da015d4c94b19962bc11622b6cc256e214256555" +dependencies = [ + "anyhow", + "heck 0.4.1", + "prettyplease", + "proc-macro2 1.0.70", + "prost-build", + "prost-reflect", + "protox", + "quote 1.0.33", + "syn 2.0.40", +] + +[[package]] +name = "zksync_state" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "mini-moka", + "tokio", + "tracing", + "vise", + "zksync_dal", + "zksync_storage", + "zksync_types", + "zksync_utils", +] + +[[package]] +name = "zksync_storage" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "num_cpus", + "once_cell", + "rocksdb", + "tracing", + "vise", +] + +[[package]] +name = "zksync_system_constants" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "anyhow", + "bigdecimal", + "hex", + "num 0.3.1", + "once_cell", + "serde", + "serde_json", + "url", + "zksync_basic_types", + "zksync_contracts", + "zksync_utils", +] + +[[package]] +name = "zksync_types" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "anyhow", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "codegen 0.1.0", + "ethereum-types 0.12.1", + "hex", + "num 0.3.1", + "num_enum", + "once_cell", + "parity-crypto", + "rlp", + "serde", + "serde_json", + "serde_with", + "strum", + "thiserror", + "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2)", + "zk_evm 1.4.0", + "zkevm_test_harness", + "zksync_basic_types", + "zksync_consensus_roles", + "zksync_contracts", + "zksync_mini_merkle_tree", + "zksync_protobuf", + "zksync_protobuf_build", + "zksync_system_constants", + "zksync_utils", +] + +[[package]] +name = "zksync_utils" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=ad-update-sc-paths#a161f013c8a1e45399b6e04157d7cac5a4d46e60" +dependencies = [ + "anyhow", + "bigdecimal", + "futures", + "hex", + "itertools 0.10.5", + "metrics", + "num 0.3.1", + "reqwest", + "serde", + "thiserror", + "tokio", + "tracing", + "vlog", + "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2)", + "zksync_basic_types", +] diff --git a/system-contracts/bootloader/test_infra/Cargo.toml b/system-contracts/bootloader/test_infra/Cargo.toml new file mode 100644 index 000000000..4eb471d93 --- /dev/null +++ b/system-contracts/bootloader/test_infra/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "test_infra" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +multivm = { git = "https://github.com/matter-labs/zksync-era.git", branch = "ad-update-sc-paths" } +zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", branch = "ad-update-sc-paths" } +zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", branch = "ad-update-sc-paths" } +zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", branch = "ad-update-sc-paths" } +zksync_state = { git = "https://github.com/matter-labs/zksync-era.git", branch = "ad-update-sc-paths" } +vlog = { git = "https://github.com/matter-labs/zksync-era.git", branch = "ad-update-sc-paths" } + +colored = "2.0" +hex = "0.4" +once_cell = "1.7" +tracing = { version = "0.1.26", features = ["log"] } +tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter", "time", "json"] } +serde_json = "1.0.67" +serde = { version = "1.0", features = ["derive"] } diff --git a/system-contracts/bootloader/test_infra/README.md b/system-contracts/bootloader/test_infra/README.md new file mode 100644 index 000000000..f66ea39ee --- /dev/null +++ b/system-contracts/bootloader/test_infra/README.md @@ -0,0 +1,15 @@ +# Testing infrastructure for bootloader + +This crate allows you to run the unittests against the bootloader code. + +You should put your tests in `../tests/bootloader/bootloader_test.yul`, then compile the yul with: + +```shell +yarn build +``` + +And afterwards run the testing infrastructure: + +```shell +cargo run +``` diff --git a/system-contracts/bootloader/test_infra/src/hook.rs b/system-contracts/bootloader/test_infra/src/hook.rs new file mode 100644 index 000000000..4dd7dfbb1 --- /dev/null +++ b/system-contracts/bootloader/test_infra/src/hook.rs @@ -0,0 +1,128 @@ +use multivm::vm_latest::{ + constants::{BOOTLOADER_HEAP_PAGE, VM_HOOK_PARAMS_START_POSITION}, + HistoryMode, SimpleMemory, +}; + +use multivm::zk_evm_1_4_0::{ + aux_structures::MemoryPage, + tracing::{BeforeExecutionData, VmLocalStateData}, + zkevm_opcode_defs::{FatPointer, Opcode, UMAOpcode}, +}; + +use zksync_types::U256; +use zksync_utils::u256_to_h256; + +#[derive(Clone, Debug)] +pub(crate) enum TestVmHook { + NoHook, + TestLog(String, String), + AssertEqFailed(String, String, String), + RequestedAssert(String), + // Testing framework reporting the number of tests. + TestCount(u32), + // 104 - test start. + TestStart(String), +} + +// Number of 32-bytes slots that are reserved for test hooks (passing information between bootloader test code and the VM). +const TEST_HOOKS: u32 = 5; +const TEST_HOOK_ENUM_POSITON: u32 = VM_HOOK_PARAMS_START_POSITION - 1; +const TEST_HOOK_START: u32 = TEST_HOOK_ENUM_POSITON - TEST_HOOKS; + +pub fn get_vm_hook_params(memory: &SimpleMemory) -> Vec { + memory.dump_page_content_as_u256_words( + BOOTLOADER_HEAP_PAGE, + TEST_HOOK_START..TEST_HOOK_ENUM_POSITON, + ) +} + +fn strip_trailing_zeros(input: &[u8]) -> &[u8] { + // Find the position of the last non-zero byte. + let end = input + .iter() + .rposition(|&byte| byte != 0) + .map(|pos| pos + 1) + .unwrap_or(0); + + // Return the byte slice up to the position found. + &input[..end] +} + +fn test_hook_as_string(hook_param: U256) -> String { + let msg = u256_to_h256(hook_param).as_bytes().to_vec(); + + String::from_utf8(strip_trailing_zeros(&msg).to_vec()).expect("Invalid debug message") +} + +fn test_hook_as_int_or_hex(hook_param: U256) -> String { + // For long data, it is better to use hex-encoding for greater readibility + if hook_param > U256::from(u64::max_value()) { + let mut bytes = [0u8; 32]; + hook_param.to_big_endian(&mut bytes); + format!("0x{}", hex::encode(bytes)) + } else { + hook_param.to_string() + } +} + +const fn heap_page_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0 + 2) +} + +impl TestVmHook { + pub(crate) fn from_opcode_memory( + state: &VmLocalStateData<'_>, + data: &BeforeExecutionData, + memory: &SimpleMemory, + ) -> Self { + let opcode_variant = data.opcode.variant; + let heap_page = + heap_page_from_base(state.vm_local_state.callstack.current.base_memory_page).0; + + let src0_value = data.src0_value.value; + + let fat_ptr = FatPointer::from_u256(src0_value); + + let value = data.src1_value.value; + + // Only UMA opcodes in the bootloader serve for vm hooks + if !matches!(opcode_variant.opcode, Opcode::UMA(UMAOpcode::HeapWrite)) + || heap_page != BOOTLOADER_HEAP_PAGE + || fat_ptr.offset != TEST_HOOK_ENUM_POSITON * 32 + { + return Self::NoHook; + } + let vm_hook_params: Vec = get_vm_hook_params(memory); + + match value.as_u32() { + 100 => Self::TestLog( + test_hook_as_string(vm_hook_params[0]), + test_hook_as_int_or_hex(vm_hook_params[1]), + ), + 101 => Self::AssertEqFailed( + test_hook_as_int_or_hex(vm_hook_params[0]), + test_hook_as_int_or_hex(vm_hook_params[1]), + test_hook_as_string(vm_hook_params[2]), + ), + 102 => Self::RequestedAssert(test_hook_as_string(vm_hook_params[0])), + 103 => Self::TestCount(vm_hook_params[0].as_u32()), + 104 => Self::TestStart(test_hook_as_string(vm_hook_params[0])), + + _ => Self::NoHook, + } + } +} + +#[cfg(test)] +mod tests { + use zksync_types::U256; + + use crate::hook::test_hook_as_string; + + #[test] + fn test_to_string() { + let data: U256 = + U256::from("0x77696c6c4661696c000000000000000000000000000000000000000000000000"); + assert_eq!("willFail", test_hook_as_string(data)); + } +} diff --git a/system-contracts/bootloader/test_infra/src/main.rs b/system-contracts/bootloader/test_infra/src/main.rs new file mode 100644 index 000000000..b8f98f18b --- /dev/null +++ b/system-contracts/bootloader/test_infra/src/main.rs @@ -0,0 +1,218 @@ +use crate::{test_count_tracer::TestCountTracer, tracer::BootloaderTestTracer}; +use colored::Colorize; +use multivm::interface::{ + L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmInterface, +}; +use multivm::vm_latest::{HistoryDisabled, ToTracerPointer, Vm}; +use once_cell::sync::OnceCell; +use std::process; + +use multivm::interface::{ExecutionResult, Halt}; +use std::{env, sync::Arc}; +use tracing_subscriber::fmt; +use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use zksync_contracts::{ + read_zbin_bytecode, BaseSystemContracts, ContractLanguage, SystemContractCode, + SystemContractsRepo, +}; +use zksync_state::{ + InMemoryStorage, StoragePtr, StorageView, IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID, +}; +use zksync_types::system_contracts::get_system_smart_contracts_from_dir; +use zksync_types::{block::legacy_miniblock_hash, Address, L1BatchNumber, MiniblockNumber, U256}; +use zksync_types::{L2ChainId, Transaction}; +use zksync_utils::bytecode::hash_bytecode; +use zksync_utils::{bytes_to_be_words, u256_to_h256}; + +mod hook; +mod test_count_tracer; +mod tracer; + +// Executes bootloader unittests. +fn execute_internal_bootloader_test() { + let test_location = env::current_dir() + .unwrap() + .join("../build/artifacts/bootloader_test.yul.zbin"); + println!("Current dir is {:?}", test_location); + let bytecode = read_zbin_bytecode(test_location.as_path()); + let hash = hash_bytecode(&bytecode); + let bootloader = SystemContractCode { + code: bytes_to_be_words(bytecode), + hash, + }; + + let repo = SystemContractsRepo { + root: env::current_dir().unwrap().join("../../"), + }; + + let bytecode = repo.read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol); + let hash = hash_bytecode(&bytecode); + let default_aa = SystemContractCode { + code: bytes_to_be_words(bytecode), + hash, + }; + + let base_system_contract = BaseSystemContracts { + bootloader, + default_aa, + }; + + let system_env = SystemEnv { + zk_porter_available: false, + version: zksync_types::ProtocolVersionId::latest(), + base_system_smart_contracts: base_system_contract, + gas_limit: u32::MAX, + execution_mode: TxExecutionMode::VerifyExecute, + default_validation_computational_gas_limit: u32::MAX, + chain_id: zksync_types::L2ChainId::from(299), + }; + + let mut l1_batch_env = L1BatchEnv { + previous_batch_hash: None, + number: L1BatchNumber::from(1), + timestamp: 14, + l1_gas_price: 250_000_000, + fair_l2_gas_price: 250_000_000, + fee_account: Address::default(), + + enforced_base_fee: None, + first_l2_block: L2BlockEnv { + number: 1, + timestamp: 15, + prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + max_virtual_blocks_to_create: 1, + }, + }; + + // First - get the number of tests. + let test_count = { + let storage: StoragePtr> = + StorageView::new(InMemoryStorage::with_custom_system_contracts_and_chain_id( + L2ChainId::from(IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID), + hash_bytecode, + get_system_smart_contracts_from_dir(env::current_dir().unwrap().join("../../")), + )) + .to_rc_ptr(); + + let mut vm: Vm<_, HistoryDisabled> = + Vm::new(l1_batch_env.clone(), system_env.clone(), storage.clone()); + + let test_count = Arc::new(OnceCell::default()); + let custom_tracers = TestCountTracer::new(test_count.clone()).into_tracer_pointer(); + + // We're using a TestCountTracer (and passing 0 as fee account) - this should cause the bootloader + // test framework to report number of tests via VM hook. + vm.inspect(custom_tracers.into(), VmExecutionMode::Bootloader); + + test_count.get().unwrap().clone() + }; + println!(" ==== Running {} tests ====", test_count); + + let mut tests_failed: u32 = 0; + + // Now we iterate over the tests. + for test_id in 1..=test_count { + println!("\n === Running test {}", test_id); + + let storage: StoragePtr> = + StorageView::new(InMemoryStorage::with_custom_system_contracts_and_chain_id( + L2ChainId::from(IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID), + hash_bytecode, + get_system_smart_contracts_from_dir(env::current_dir().unwrap().join("../../")), + )) + .to_rc_ptr(); + + // We are passing id of the test in location (0) where we normally put the operator. + // This is then picked up by the testing framework. + l1_batch_env.fee_account = zksync_types::H160::from(u256_to_h256(U256::from(test_id))); + let mut vm: Vm<_, HistoryDisabled> = + Vm::new(l1_batch_env.clone(), system_env.clone(), storage.clone()); + let test_result = Arc::new(OnceCell::default()); + let requested_assert = Arc::new(OnceCell::default()); + let test_name = Arc::new(OnceCell::default()); + + let custom_tracers = BootloaderTestTracer::new( + test_result.clone(), + requested_assert.clone(), + test_name.clone(), + ) + .into_tracer_pointer(); + + // Let's insert transactions into slots. They are not executed, but the tests can run functions against them. + let json_str = include_str!("test_transactions/0.json"); + let tx: Transaction = serde_json::from_str(json_str).unwrap(); + vm.push_transaction(tx); + + let result = vm.inspect(custom_tracers.into(), VmExecutionMode::Bootloader); + let mut test_result = Arc::into_inner(test_result).unwrap().into_inner(); + let requested_assert = Arc::into_inner(requested_assert).unwrap().into_inner(); + let test_name = Arc::into_inner(test_name) + .unwrap() + .into_inner() + .unwrap_or_default(); + + if test_result.is_none() { + test_result = Some(if let Some(requested_assert) = requested_assert { + match &result.result { + ExecutionResult::Success { .. } => Err(format!( + "Should have failed with {}, but run succesfully.", + requested_assert + )), + ExecutionResult::Revert { output } => Err(format!( + "Should have failed with {}, but run reverted with {}.", + requested_assert, + output.to_user_friendly_string() + )), + ExecutionResult::Halt { reason } => { + if let Halt::UnexpectedVMBehavior(reason) = reason { + let reason = reason.strip_prefix("Assertion error: ").unwrap(); + if reason == requested_assert { + Ok(()) + } else { + Err(format!( + "Should have failed with `{}`, but failed with different assert `{}`", + requested_assert, reason + )) + } + } else { + Err(format!( + "Should have failed with `{}`, but halted with`{}`", + requested_assert, reason + )) + } + } + } + } else { + match &result.result { + ExecutionResult::Success { .. } => Ok(()), + ExecutionResult::Revert { output } => Err(output.to_user_friendly_string()), + ExecutionResult::Halt { reason } => Err(reason.to_string()), + } + }); + } + + match &test_result.unwrap() { + Ok(_) => println!("{} {}", "[PASS]".green(), test_name), + Err(error_info) => { + tests_failed += 1; + println!("{} {} {}", "[FAIL]".red(), test_name, error_info) + } + } + } + if tests_failed > 0 { + println!("{}", format!("{} tests failed.", tests_failed).red()); + process::exit(1); + } else { + println!("{}", "ALL tests passed.".green()) + } +} + +fn main() { + tracing_subscriber::registry() + .with(fmt::Layer::default()) + .with(tracing_subscriber::EnvFilter::from_default_env()) + .init(); + + execute_internal_bootloader_test(); +} diff --git a/system-contracts/bootloader/test_infra/src/test_count_tracer.rs b/system-contracts/bootloader/test_infra/src/test_count_tracer.rs new file mode 100644 index 000000000..638e17bfe --- /dev/null +++ b/system-contracts/bootloader/test_infra/src/test_count_tracer.rs @@ -0,0 +1,42 @@ +use std::sync::Arc; + +use multivm::interface::dyn_tracers::vm_1_4_0::DynTracer; +use multivm::vm_latest::{HistoryMode, SimpleMemory, VmTracer}; +use multivm::zk_evm_1_4_0::tracing::{BeforeExecutionData, VmLocalStateData}; +use once_cell::sync::OnceCell; +use zksync_state::{StoragePtr, WriteStorage}; + +use crate::hook::TestVmHook; + +/// Tracer that returns number of tests in the bootloader test file. +pub struct TestCountTracer { + /// Returns number of tests in the yul file. + pub test_count: Arc>, +} + +impl TestCountTracer { + /// Creates the tracer that should also report the amount of tests in a file. + pub fn new(test_count_result: Arc>) -> Self { + TestCountTracer { + test_count: test_count_result, + } + } +} + +impl DynTracer> for TestCountTracer { + fn before_execution( + &mut self, + state: VmLocalStateData<'_>, + data: BeforeExecutionData, + memory: &SimpleMemory, + _storage: StoragePtr, + ) { + if let TestVmHook::TestCount(test_count) = + TestVmHook::from_opcode_memory(&state, &data, memory) + { + self.test_count.set(test_count).unwrap(); + } + } +} + +impl VmTracer for TestCountTracer {} diff --git a/system-contracts/bootloader/test_infra/src/test_transactions/0.json b/system-contracts/bootloader/test_infra/src/test_transactions/0.json new file mode 100644 index 000000000..0edb7a922 --- /dev/null +++ b/system-contracts/bootloader/test_infra/src/test_transactions/0.json @@ -0,0 +1,46 @@ +{ + "common_data": { + "L2": { + "nonce": 1, + "fee": { + "gas_limit": "0xfd617", + "max_fee_per_gas": "0xee6b280", + "max_priority_fee_per_gas": "0x0", + "gas_per_pubdata_limit": "0xc350" + }, + "initiatorAddress": "0x36615cf349d7f6344891b1e7ca7c72883f5dc049", + "signature": [ + 132, 90, 248, 214, 198, 24, 213, 194, 29, 253, 36, 112, 77, 245, 167, 245, 245, 120, 200, 225, 31, 40, 16, 76, + 182, 155, 102, 8, 166, 115, 59, 80, 92, 183, 251, 203, 109, 202, 149, 230, 132, 173, 160, 72, 234, 181, 177, 31, + 224, 177, 28, 52, 251, 76, 107, 79, 160, 132, 47, 135, 199, 146, 71, 193, 28 + ], + "transactionType": "EIP712Transaction", + "input": { + "hash": "0xf415e63408ab712fa72f7931ba8e1f21f9d5e86a2a76fb6857fe7efb84ac8ed4", + "data": [ + 113, 248, 236, 1, 128, 132, 14, 230, 178, 128, 131, 15, 214, 23, 148, 17, 28, 62, 137, 206, 128, 230, 46, 232, + 131, 24, 194, 128, 73, 32, 212, 201, 111, 146, 187, 128, 184, 100, 164, 19, 104, 98, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 75, 105, 108, 108, 101, 114, 32, 99, 111, 109, + 98, 111, 32, 49, 52, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 1, 4, 128, 128, 130, 1, 4, 148, + 54, 97, 92, 243, 73, 215, 246, 52, 72, 145, 177, 231, 202, 124, 114, 136, 63, 93, 192, 73, 130, 195, 80, 192, + 184, 65, 132, 90, 248, 214, 198, 24, 213, 194, 29, 253, 36, 112, 77, 245, 167, 245, 245, 120, 200, 225, 31, + 40, 16, 76, 182, 155, 102, 8, 166, 115, 59, 80, 92, 183, 251, 203, 109, 202, 149, 230, 132, 173, 160, 72, 234, + 181, 177, 31, 224, 177, 28, 52, 251, 76, 107, 79, 160, 132, 47, 135, 199, 146, 71, 193, 28, 192 + ] + }, + "paymasterParams": { + "paymaster": "0x0000000000000000000000000000000000000000", + "paymasterInput": [] + } + } + }, + "execute": { + "contractAddress": "0x111c3e89ce80e62ee88318c2804920d4c96f92bb", + "calldata": "0xa4136862000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000104b696c6c657220636f6d626f2031343400000000000000000000000000000000", + "value": "0x0", + "factoryDeps": [] + }, + "received_timestamp_ms": 1695015132601, + "raw_bytes": "0x71f8ec0180840ee6b280830fd61794111c3e89ce80e62ee88318c2804920d4c96f92bb80b864a4136862000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000104b696c6c657220636f6d626f203134340000000000000000000000000000000082010480808201049436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c0b841845af8d6c618d5c21dfd24704df5a7f5f578c8e11f28104cb69b6608a6733b505cb7fbcb6dca95e684ada048eab5b11fe0b11c34fb4c6b4fa0842f87c79247c11cc0" +} diff --git a/system-contracts/bootloader/test_infra/src/test_transactions/README.md b/system-contracts/bootloader/test_infra/src/test_transactions/README.md new file mode 100644 index 000000000..ee6c11780 --- /dev/null +++ b/system-contracts/bootloader/test_infra/src/test_transactions/README.md @@ -0,0 +1,8 @@ +# Test Transactions + +This directory contains JSON serialized 'Transaction' objects that are inserted into bootloader memory during +unittesting. + +Please add files with consecutive numbers (0.json, 1.json) - and insert into bootloader in the same order. + +Then, they can be accessed in the unittest, by calling `testing_txDataOffset(x)`. diff --git a/system-contracts/bootloader/test_infra/src/tracer.rs b/system-contracts/bootloader/test_infra/src/tracer.rs new file mode 100644 index 000000000..85ab0428b --- /dev/null +++ b/system-contracts/bootloader/test_infra/src/tracer.rs @@ -0,0 +1,84 @@ +use std::sync::Arc; + +use colored::Colorize; +use once_cell::sync::OnceCell; + +use multivm::interface::{ + dyn_tracers::vm_1_4_0::DynTracer, + tracer::{TracerExecutionStatus, TracerExecutionStopReason}, +}; +use multivm::vm_latest::{BootloaderState, HistoryMode, SimpleMemory, VmTracer, ZkSyncVmState}; +use multivm::zk_evm_1_4_0::tracing::{BeforeExecutionData, VmLocalStateData}; + +use zksync_state::{StoragePtr, WriteStorage}; + +use crate::hook::TestVmHook; + +/// Bootloader test tracer that is executing while the bootloader tests are running. +/// It can check the assers, return information about the running tests (and amount of tests) etc. +pub struct BootloaderTestTracer { + /// Set if the currently running test has failed. + test_result: Arc>>, + /// Set, if the currently running test should fail with a given assert. + requested_assert: Arc>, + + test_name: Arc>, +} + +impl BootloaderTestTracer { + pub fn new( + test_result: Arc>>, + requested_assert: Arc>, + test_name: Arc>, + ) -> Self { + BootloaderTestTracer { + test_result, + requested_assert, + test_name, + } + } +} + +impl DynTracer> for BootloaderTestTracer { + fn before_execution( + &mut self, + state: VmLocalStateData<'_>, + data: BeforeExecutionData, + memory: &SimpleMemory, + _storage: StoragePtr, + ) { + let hook = TestVmHook::from_opcode_memory(&state, &data, memory); + + if let TestVmHook::TestLog(msg, data_str) = &hook { + println!("{} {} {}", "Test log".bold(), msg, data_str); + } + if let TestVmHook::AssertEqFailed(a, b, msg) = &hook { + let result = format!("Assert failed: {} is not equal to {}: {}", a, b, msg); + + self.test_result.set(Err(result.clone())).unwrap(); + } + if let TestVmHook::RequestedAssert(requested_assert) = &hook { + let _ = self.requested_assert.set(requested_assert.clone()); + } + + if let TestVmHook::TestStart(test_name) = &hook { + self.test_name + .set(test_name.clone()) + .expect("Test already started"); + } + } +} + +impl VmTracer for BootloaderTestTracer { + fn finish_cycle( + &mut self, + _state: &mut ZkSyncVmState, + _bootloader_state: &mut BootloaderState, + ) -> TracerExecutionStatus { + if let Some(Err(_)) = self.test_result.get() { + TracerExecutionStatus::Stop(TracerExecutionStopReason::Finish) + } else { + TracerExecutionStatus::Continue + } + } +} diff --git a/system-contracts/bootloader/tests/README.md b/system-contracts/bootloader/tests/README.md new file mode 100644 index 000000000..31acb0ecf --- /dev/null +++ b/system-contracts/bootloader/tests/README.md @@ -0,0 +1,23 @@ +# Testing + +## Full tests + +`dummy.yul` and `transfer_tests.yul` are full Yul files, which are replacing the bootloader, and are used in +`zksync-era` crate. + +## Unittests + +Please put bootloader unittests in `bootloader/bootloader_test.yul` file, and any testing utility functions in +`utils/test_utils.yul`. + +To execute tests, you should first run yarn to prepare the source code: + +```shell +yarn preprocess && yarn compile-yul +``` + +And then run the test framework: + +```shell +cd test_infa && cargo run +``` diff --git a/system-contracts/bootloader/tests/bootloader/bootloader_test.yul b/system-contracts/bootloader/tests/bootloader/bootloader_test.yul new file mode 100644 index 000000000..cd41c45d0 --- /dev/null +++ b/system-contracts/bootloader/tests/bootloader/bootloader_test.yul @@ -0,0 +1,52 @@ +function TEST_safeSub() { + testing_assertEq(safeSub(10, 7, "err"), 3, "Failed to subtract 7") + testing_assertEq(safeSub(10, 8, "err"), 2, "Failed to subtract 8") +} + +function TEST_safeDiv() { + testing_assertEq(safeDiv(4, 2, "err"), 2, "Simple division") + testing_assertEq(safeDiv(5, 2, "err"), 2, "Rouding") + testing_assertEq(safeDiv(5, 3, "err"), 1, "Rouding down") + testing_assertEq(safeDiv(4, 3, "err"), 1, "Rouding down") + testing_assertEq(safeDiv(0, 3, "err"), 0, "Rouding down") +} +function TEST_safeDivAssert() { + testing_testWillFailWith("divByZero") + safeDiv(4, 0, "divByZero") +} + +function TEST_asserts() { + testing_testWillFailWith("willFail") + safeSub(10, 12, "willFail") +} + +function TEST_safeMul() { + testing_assertEq(safeMul(4, 2, "err"), 8, "Simple") + testing_assertEq(safeMul(0, 2, "err"), 0, "With zero") + testing_assertEq(safeMul(0, 0, "err"), 0, "With zero") + testing_assertEq(safeMul(2, 0, "err"), 0, "With zero") +} + +function TEST_safeMulAssert() { + testing_testWillFailWith("overflow") + let left := shl(129, 1) + testing_log("left", left) + safeMul(left, left, "overflow") +} + +// function TEST_should ignore + +function TEST_strLen() { + testing_assertEq(getStrLen("abcd"), 4, "short string") + testing_assertEq(getStrLen("00"), 2, "0 filled string") + testing_assertEq(getStrLen(""), 0, "empty string") + testing_assertEq(getStrLen("12345678901234567890123456789012"), 32, "max length") + testing_assertEq(getStrLen("1234567890123456789012345678901234"), 0, "over max length") +} + +function TEST_simple_transaction() { + // We'll test the transaction from 0.json + let txDataOffset := testing_txDataOffset(0) + let innerTxDataOffset := add(txDataOffset, 0x20) + testing_assertEq(getGasPerPubdataByteLimit(innerTxDataOffset), 0xc350, "Invalid pubdata limit") +} diff --git a/system-contracts/bootloader/tests/dummy.yul b/system-contracts/bootloader/tests/dummy.yul new file mode 100644 index 000000000..49970154e --- /dev/null +++ b/system-contracts/bootloader/tests/dummy.yul @@ -0,0 +1,15 @@ +// A really basic test that only sets one memory cell to 1. +object "Bootloader" { + code { + } + object "Bootloader_deployed" { + code { + let DUMMY_TEST_CELL := 0x00 + let DUMMY_TEST_VALUE := 0x123123123 + mstore(DUMMY_TEST_CELL, DUMMY_TEST_VALUE) + // Need to return. Otherwise, the compiler will optimize out + // the mstore + return(0,32) + } + } +} diff --git a/system-contracts/bootloader/tests/transfer_test.yul b/system-contracts/bootloader/tests/transfer_test.yul new file mode 100644 index 000000000..460ff0a88 --- /dev/null +++ b/system-contracts/bootloader/tests/transfer_test.yul @@ -0,0 +1,46 @@ +// A really basic test that only sets one memory cell to 1. +object "Bootloader" { + code { + } + object "Bootloader_deployed" { + code { + // This test is used to calculate the number of gas required to + // do a simple internal transfer + + function ETH_L2_TOKEN_ADDR() -> ret { + ret := 0x000000000000000000000000000000000000800a + } + function BOOTLOADER_FORMAL_ADDR() -> ret { + ret := 0x0000000000000000000000000000000000008001 + } + + // Getting the balance of the account in order to make sure + // that the decommit of the account has already happened and so + // the call of the actual transfer is cheaper. + let myBalance := selfbalance() + // Storing the value to avoid compiler optimization + mstore(100, myBalance) + + let gasBeforeCall := gas() + let transferSuccess := call( + gas(), + ETH_L2_TOKEN_ADDR(), + 0, + 0, + 100, + 0, + 0 + ) + let gasSpent := sub(gasBeforeCall, gas()) + + if iszero(transferSuccess) { + // The transfer should succeed + revert(0,0) + } + + + mstore(0, gasSpent) + return(0, 256) + } + } +} diff --git a/system-contracts/bootloader/tests/utils/test_utils.yul b/system-contracts/bootloader/tests/utils/test_utils.yul new file mode 100644 index 000000000..1d2e3e65e --- /dev/null +++ b/system-contracts/bootloader/tests/utils/test_utils.yul @@ -0,0 +1,55 @@ + + +// We're locating the test hooks 'before' the last free slot. +function TEST_HOOK_PTR() -> ret { + ret := LAST_FREE_SLOT() +} + +function TEST_HOOK_PARAMS_OFFSET() -> ret { + ret := sub(TEST_HOOK_PTR(), mul(5, 32)) +} + +function setTestHook(hook) { + mstore(TEST_HOOK_PTR(), $llvm_NoInline_llvm$_unoptimized(hook)) +} + +function storeTestHookParam(paramId, value) { + let offset := add(TEST_HOOK_PARAMS_OFFSET(), mul(32, paramId)) + mstore(offset, $llvm_NoInline_llvm$_unoptimized(value)) +} + + +function testing_log(msg, data) { + storeTestHookParam(0, msg) + storeTestHookParam(1, data) + setTestHook(100) +} + +function testing_start(test_name) { + storeTestHookParam(0, test_name) + setTestHook(104) +} + +function testing_assertEq(a, b, message) { + if iszero(eq(a, b)) { + storeTestHookParam(0, a) + storeTestHookParam(1, b) + storeTestHookParam(2, message) + setTestHook(101) + } +} + +function testing_testWillFailWith(message) { + storeTestHookParam(0, $llvm_NoInline_llvm$_unoptimized(message)) + setTestHook(102) +} +function testing_totalTests(tests) { + storeTestHookParam(0, $llvm_NoInline_llvm$_unoptimized(tests)) + setTestHook(103) +} + +// Returns txDataOffset for the index transaction. +function testing_txDataOffset(index) -> txDataOffset { + let txPtr := add(TX_DESCRIPTION_BEGIN_BYTE(), mul(index, TX_DESCRIPTION_SIZE())) + txDataOffset := mload(add(txPtr, 0x20)) +} diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol new file mode 100644 index 000000000..d5027f2f5 --- /dev/null +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./interfaces/IAccountCodeStorage.sol"; +import "./libraries/Utils.sol"; +import {DEPLOYER_SYSTEM_CONTRACT, NONCE_HOLDER_SYSTEM_CONTRACT, CURRENT_MAX_PRECOMPILE_ADDRESS} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The storage of this contract serves as a mapping for the code hashes of the 32-byte account addresses. + * @dev Code hash is not strictly a hash, it's a structure where the first byte denotes the version of the hash, + * the second byte denotes whether the contract is constructed, and the next two bytes denote the length in 32-byte words. + * And then the next 28 bytes are the truncated hash. + * @dev In this version of zkSync, the first byte of the hash MUST be 1. + * @dev The length of each bytecode MUST be odd. It's internal code format requirements, due to padding of SHA256 function. + * @dev It is also assumed that all the bytecode hashes are *known*, i.e. the full bytecodes + * were published on L1 as calldata. This contract trusts the ContractDeployer and the KnownCodesStorage + * system contracts to enforce the invariants mentioned above. + */ +contract AccountCodeStorage is IAccountCodeStorage { + bytes32 constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + + modifier onlyDeployer() { + require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract"); + _; + } + + /// @notice Stores the bytecodeHash of constructing contract. + /// @param _address The address of the account to set the codehash to. + /// @param _hash The new bytecode hash of the constructing account. + /// @dev This method trusts the ContractDeployer to make sure that the bytecode is known and well-formed, + /// but checks whether the bytecode hash corresponds to the constructing smart contract. + function storeAccountConstructingCodeHash(address _address, bytes32 _hash) external override onlyDeployer { + // Check that code hash corresponds to the deploying smart contract + require(Utils.isContractConstructing(_hash), "Code hash is not for a contract on constructor"); + _storeCodeHash(_address, _hash); + } + + /// @notice Stores the bytecodeHash of constructed contract. + /// @param _address The address of the account to set the codehash to. + /// @param _hash The new bytecode hash of the constructed account. + /// @dev This method trusts the ContractDeployer to make sure that the bytecode is known and well-formed, + /// but checks whether the bytecode hash corresponds to the constructed smart contract. + function storeAccountConstructedCodeHash(address _address, bytes32 _hash) external override onlyDeployer { + // Check that code hash corresponds to the deploying smart contract + require(Utils.isContractConstructed(_hash), "Code hash is not for a constructed contract"); + _storeCodeHash(_address, _hash); + } + + /// @notice Marks the account bytecodeHash as constructed. + /// @param _address The address of the account to mark as constructed + function markAccountCodeHashAsConstructed(address _address) external override onlyDeployer { + bytes32 codeHash = getRawCodeHash(_address); + + require(Utils.isContractConstructing(codeHash), "Code hash is not for a contract on constructor"); + + // Get the bytecode hash with "isConstructor" flag equal to false + bytes32 constructedBytecodeHash = Utils.constructedBytecodeHash(codeHash); + + _storeCodeHash(_address, constructedBytecodeHash); + } + + /// @dev Store the codehash of the account without any checks. + /// @param _address The address of the account to set the codehash to. + /// @param _hash The new account bytecode hash. + function _storeCodeHash(address _address, bytes32 _hash) internal { + uint256 addressAsKey = uint256(uint160(_address)); + assembly { + sstore(addressAsKey, _hash) + } + } + + /// @notice Get the codehash stored for an address. + /// @param _address The address of the account of which the codehash to return + /// @return codeHash The codehash stored for this account. + function getRawCodeHash(address _address) public view override returns (bytes32 codeHash) { + uint256 addressAsKey = uint256(uint160(_address)); + + assembly { + codeHash := sload(addressAsKey) + } + } + + /// @notice Simulate the behavior of the `extcodehash` EVM opcode. + /// @param _input The 256-bit account address. + /// @return codeHash - hash of the bytecode according to the EIP-1052 specification. + function getCodeHash(uint256 _input) external view override returns (bytes32) { + // We consider the account bytecode hash of the last 20 bytes of the input, because + // according to the spec "If EXTCODEHASH of A is X, then EXTCODEHASH of A + 2**160 is X". + address account = address(uint160(_input)); + if (uint160(account) <= CURRENT_MAX_PRECOMPILE_ADDRESS) { + return EMPTY_STRING_KECCAK; + } + + bytes32 codeHash = getRawCodeHash(account); + + // The code hash is equal to the `keccak256("")` if the account is an EOA with at least one transaction. + // Otherwise, the account is either deployed smart contract or an empty account, + // for both cases the code hash is equal to the raw code hash. + if (codeHash == 0x00 && NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(account) > 0) { + codeHash = EMPTY_STRING_KECCAK; + } + // The contract is still on the constructor, which means it is not deployed yet, + // so set `keccak256("")` as a code hash. The EVM has the same behavior. + else if (Utils.isContractConstructing(codeHash)) { + codeHash = EMPTY_STRING_KECCAK; + } + + return codeHash; + } + + /// @notice Simulate the behavior of the `extcodesize` EVM opcode. + /// @param _input The 256-bit account address. + /// @return codeSize - the size of the deployed smart contract in bytes. + function getCodeSize(uint256 _input) external view override returns (uint256 codeSize) { + // We consider the account bytecode size of the last 20 bytes of the input, because + // according to the spec "If EXTCODESIZE of A is X, then EXTCODESIZE of A + 2**160 is X". + address account = address(uint160(_input)); + bytes32 codeHash = getRawCodeHash(account); + + // If the contract is a default account or is on constructor the code size is zero, + // otherwise extract the proper value for it from the bytecode hash. + // NOTE: zero address and precompiles are a special case, they are contracts, but we + // want to preserve EVM invariants (see EIP-1052 specification). That's why we automatically + // return `0` length in the following cases: + // - `codehash(0) == 0` + // - `account` is a precompile. + // - `account` is currently being constructed + if ( + uint160(account) > CURRENT_MAX_PRECOMPILE_ADDRESS && + codeHash != 0x00 && + !Utils.isContractConstructing(codeHash) + ) { + codeSize = Utils.bytecodeLenInBytes(codeHash); + } + } +} diff --git a/system-contracts/contracts/BootloaderUtilities.sol b/system-contracts/contracts/BootloaderUtilities.sol new file mode 100644 index 000000000..49467bdc2 --- /dev/null +++ b/system-contracts/contracts/BootloaderUtilities.sol @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./interfaces/IBootloaderUtilities.sol"; +import "./libraries/TransactionHelper.sol"; +import "./libraries/RLPEncoder.sol"; +import "./libraries/EfficientCall.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice A contract that provides some utility methods for the bootloader + * that is very hard to write in Yul. + */ +contract BootloaderUtilities is IBootloaderUtilities { + using TransactionHelper for *; + + /// @notice Calculates the canonical transaction hash and the recommended transaction hash. + /// @param _transaction The transaction. + /// @return txHash and signedTxHash of the transaction, i.e. the transaction hash to be used in the explorer and commits to all + /// the fields of the transaction and the recommended hash to be signed for this transaction. + /// @dev txHash must be unique for all transactions. + function getTransactionHashes( + Transaction calldata _transaction + ) external view override returns (bytes32 txHash, bytes32 signedTxHash) { + signedTxHash = _transaction.encodeHash(); + if (_transaction.txType == EIP_712_TX_TYPE) { + txHash = keccak256(bytes.concat(signedTxHash, EfficientCall.keccak(_transaction.signature))); + } else if (_transaction.txType == LEGACY_TX_TYPE) { + txHash = encodeLegacyTransactionHash(_transaction); + } else if (_transaction.txType == EIP_1559_TX_TYPE) { + txHash = encodeEIP1559TransactionHash(_transaction); + } else if (_transaction.txType == EIP_2930_TX_TYPE) { + txHash = encodeEIP2930TransactionHash(_transaction); + } else { + revert("Unsupported tx type"); + } + } + + /// @notice Calculates the hash for a legacy transaction. + /// @param _transaction The legacy transaction. + /// @return txHash The hash of the transaction. + function encodeLegacyTransactionHash(Transaction calldata _transaction) internal view returns (bytes32 txHash) { + // Hash of legacy transactions are encoded as one of the: + // - RLP(nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0) + // - RLP(nonce, gasPrice, gasLimit, to, value, data) + // + // In this RLP encoding, only the first one above list appears, so we encode each element + // inside list and then concatenate the length of all elements with them. + + bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); + // Encode `gasPrice` and `gasLimit` together to prevent "stack too deep error". + bytes memory encodedGasParam; + { + bytes memory encodedGasPrice = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); + bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); + encodedGasParam = bytes.concat(encodedGasPrice, encodedGasLimit); + } + + bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); + // Encode only the length of the transaction data, and not the data itself, + // so as not to copy to memory a potentially huge transaction data twice. + bytes memory encodedDataLength; + { + // Safe cast, because the length of the transaction data can't be so large. + uint64 txDataLen = uint64(_transaction.data.length); + if (txDataLen != 1) { + // If the length is not equal to one, then only using the length can it be encoded definitely. + encodedDataLength = RLPEncoder.encodeNonSingleBytesLen(txDataLen); + } else if (_transaction.data[0] >= 0x80) { + // If input is a byte in [0x80, 0xff] range, RLP encoding will concatenates 0x81 with the byte. + encodedDataLength = hex"81"; + } + // Otherwise the length is not encoded at all. + } + + bytes memory rEncoded; + { + uint256 rInt = uint256(bytes32(_transaction.signature[0:32])); + rEncoded = RLPEncoder.encodeUint256(rInt); + } + bytes memory sEncoded; + { + uint256 sInt = uint256(bytes32(_transaction.signature[32:64])); + sEncoded = RLPEncoder.encodeUint256(sInt); + } + bytes memory vEncoded; + { + uint256 vInt = uint256(uint8(_transaction.signature[64])); + require(vInt == 27 || vInt == 28, "Invalid v value"); + + // If the `chainId` is specified in the transaction, then the `v` value is encoded as + // `35 + y + 2 * chainId == vInt + 8 + 2 * chainId`, where y - parity bit (see EIP-155). + if (_transaction.reserved[0] != 0) { + vInt += 8 + block.chainid * 2; + } + + vEncoded = RLPEncoder.encodeUint256(vInt); + } + + bytes memory encodedListLength; + unchecked { + uint256 listLength = encodedNonce.length + + encodedGasParam.length + + encodedTo.length + + encodedValue.length + + encodedDataLength.length + + _transaction.data.length + + rEncoded.length + + sEncoded.length + + vEncoded.length; + + // Safe cast, because the length of the list can't be so large. + encodedListLength = RLPEncoder.encodeListLen(uint64(listLength)); + } + + return + keccak256( + bytes.concat( + encodedListLength, + encodedNonce, + encodedGasParam, + encodedTo, + encodedValue, + encodedDataLength, + _transaction.data, + vEncoded, + rEncoded, + sEncoded + ) + ); + } + + /// @notice Calculates the hash for an EIP2930 transaction. + /// @param _transaction The EIP2930 transaction. + /// @return txHash The hash of the transaction. + function encodeEIP2930TransactionHash(Transaction calldata _transaction) internal view returns (bytes32) { + // Encode all fixed-length params to avoid "stack too deep error" + bytes memory encodedFixedLengthParams; + { + bytes memory encodedChainId = RLPEncoder.encodeUint256(block.chainid); + bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); + bytes memory encodedGasPrice = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); + bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); + bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); + encodedFixedLengthParams = bytes.concat( + encodedChainId, + encodedNonce, + encodedGasPrice, + encodedGasLimit, + encodedTo, + encodedValue + ); + } + + // Encode only the length of the transaction data, and not the data itself, + // so as not to copy to memory a potentially huge transaction data twice. + bytes memory encodedDataLength; + { + // Safe cast, because the length of the transaction data can't be so large. + uint64 txDataLen = uint64(_transaction.data.length); + if (txDataLen != 1) { + // If the length is not equal to one, then only using the length can it be encoded definitely. + encodedDataLength = RLPEncoder.encodeNonSingleBytesLen(txDataLen); + } else if (_transaction.data[0] >= 0x80) { + // If input is a byte in [0x80, 0xff] range, RLP encoding will concatenates 0x81 with the byte. + encodedDataLength = hex"81"; + } + // Otherwise the length is not encoded at all. + } + + // On zkSync, access lists are always zero length (at least for now). + bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); + + bytes memory rEncoded; + { + uint256 rInt = uint256(bytes32(_transaction.signature[0:32])); + rEncoded = RLPEncoder.encodeUint256(rInt); + } + bytes memory sEncoded; + { + uint256 sInt = uint256(bytes32(_transaction.signature[32:64])); + sEncoded = RLPEncoder.encodeUint256(sInt); + } + bytes memory vEncoded; + { + uint256 vInt = uint256(uint8(_transaction.signature[64])); + require(vInt == 27 || vInt == 28, "Invalid v value"); + + vEncoded = RLPEncoder.encodeUint256(vInt - 27); + } + + bytes memory encodedListLength; + unchecked { + uint256 listLength = encodedFixedLengthParams.length + + encodedDataLength.length + + _transaction.data.length + + encodedAccessListLength.length + + rEncoded.length + + sEncoded.length + + vEncoded.length; + + // Safe cast, because the length of the list can't be so large. + encodedListLength = RLPEncoder.encodeListLen(uint64(listLength)); + } + + return + keccak256( + bytes.concat( + "\x01", + encodedListLength, + encodedFixedLengthParams, + encodedDataLength, + _transaction.data, + encodedAccessListLength, + vEncoded, + rEncoded, + sEncoded + ) + ); + } + + /// @notice Calculates the hash for an EIP1559 transaction. + /// @param _transaction The legacy transaction. + /// @return txHash The hash of the transaction. + function encodeEIP1559TransactionHash(Transaction calldata _transaction) internal view returns (bytes32) { + // The formula for hash of EIP1559 transaction in the original proposal: + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md + + // Encode all fixed-length params to avoid "stack too deep error" + bytes memory encodedFixedLengthParams; + { + bytes memory encodedChainId = RLPEncoder.encodeUint256(block.chainid); + bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); + bytes memory encodedMaxPriorityFeePerGas = RLPEncoder.encodeUint256(_transaction.maxPriorityFeePerGas); + bytes memory encodedMaxFeePerGas = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); + bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); + bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); + encodedFixedLengthParams = bytes.concat( + encodedChainId, + encodedNonce, + encodedMaxPriorityFeePerGas, + encodedMaxFeePerGas, + encodedGasLimit, + encodedTo, + encodedValue + ); + } + + // Encode only the length of the transaction data, and not the data itself, + // so as not to copy to memory a potentially huge transaction data twice. + bytes memory encodedDataLength; + { + // Safe cast, because the length of the transaction data can't be so large. + uint64 txDataLen = uint64(_transaction.data.length); + if (txDataLen != 1) { + // If the length is not equal to one, then only using the length can it be encoded definitely. + encodedDataLength = RLPEncoder.encodeNonSingleBytesLen(txDataLen); + } else if (_transaction.data[0] >= 0x80) { + // If input is a byte in [0x80, 0xff] range, RLP encoding will concatenates 0x81 with the byte. + encodedDataLength = hex"81"; + } + // Otherwise the length is not encoded at all. + } + + // On zkSync, access lists are always zero length (at least for now). + bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); + + bytes memory rEncoded; + { + uint256 rInt = uint256(bytes32(_transaction.signature[0:32])); + rEncoded = RLPEncoder.encodeUint256(rInt); + } + bytes memory sEncoded; + { + uint256 sInt = uint256(bytes32(_transaction.signature[32:64])); + sEncoded = RLPEncoder.encodeUint256(sInt); + } + bytes memory vEncoded; + { + uint256 vInt = uint256(uint8(_transaction.signature[64])); + require(vInt == 27 || vInt == 28, "Invalid v value"); + + vEncoded = RLPEncoder.encodeUint256(vInt - 27); + } + + bytes memory encodedListLength; + unchecked { + uint256 listLength = encodedFixedLengthParams.length + + encodedDataLength.length + + _transaction.data.length + + encodedAccessListLength.length + + rEncoded.length + + sEncoded.length + + vEncoded.length; + + // Safe cast, because the length of the list can't be so large. + encodedListLength = RLPEncoder.encodeListLen(uint64(listLength)); + } + + return + keccak256( + bytes.concat( + "\x02", + encodedListLength, + encodedFixedLengthParams, + encodedDataLength, + _transaction.data, + encodedAccessListLength, + vEncoded, + rEncoded, + sEncoded + ) + ); + } +} diff --git a/system-contracts/contracts/ComplexUpgrader.sol b/system-contracts/contracts/ComplexUpgrader.sol new file mode 100644 index 000000000..2f4d886cd --- /dev/null +++ b/system-contracts/contracts/ComplexUpgrader.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {IComplexUpgrader} from "./interfaces/IComplexUpgrader.sol"; +import {FORCE_DEPLOYER} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Upgrader which should be used to perform complex multistep upgrades on L2. In case some custom logic for an upgrade is needed + * this logic should be deployed into the user space and then this contract will delegatecall to the deployed contract. + */ +contract ComplexUpgrader is IComplexUpgrader { + /// @notice Executes an upgrade process by delegating calls to another contract. + /// @dev This function allows only the `FORCE_DEPLOYER` to initiate the upgrade. + /// If the delegate call fails, the function will revert the transaction, returning the error message + /// provided by the delegated contract. + /// @param _delegateTo the address of the contract to which the calls will be delegated + /// @param _calldata the calldata to be delegate called in the `_delegateTo` contract + function upgrade(address _delegateTo, bytes calldata _calldata) external payable { + require(msg.sender == FORCE_DEPLOYER, "Can only be called by FORCE_DEPLOYER"); + + require(_delegateTo.code.length > 0, "Delegatee is an EOA"); + (bool success, bytes memory returnData) = _delegateTo.delegatecall(_calldata); + assembly { + if iszero(success) { + revert(add(returnData, 0x20), mload(returnData)) + } + } + } +} diff --git a/system-contracts/contracts/Compressor.sol b/system-contracts/contracts/Compressor.sol new file mode 100644 index 000000000..24aac725a --- /dev/null +++ b/system-contracts/contracts/Compressor.sol @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {ICompressor, OPERATION_BITMASK, LENGTH_BITS_OFFSET, MAX_ENUMERATION_INDEX_SIZE} from "./interfaces/ICompressor.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {Utils} from "./libraries/Utils.sol"; +import {UnsafeBytesCalldata} from "./libraries/UnsafeBytesCalldata.sol"; +import {EfficientCall} from "./libraries/EfficientCall.sol"; +import {L1_MESSENGER_CONTRACT, INITIAL_WRITE_STARTING_POSITION, COMPRESSED_INITIAL_WRITE_SIZE, STATE_DIFF_ENTRY_SIZE, STATE_DIFF_ENUM_INDEX_OFFSET, STATE_DIFF_FINAL_VALUE_OFFSET, STATE_DIFF_DERIVED_KEY_OFFSET, DERIVED_KEY_LENGTH, VALUE_LENGTH, ENUM_INDEX_LENGTH, KNOWN_CODE_STORAGE_CONTRACT} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Contract with code pertaining to compression for zkEVM; at the moment this is used for bytecode compression + * and state diff compression validation. + * @dev Every deployed bytecode/published state diffs in zkEVM should be publicly restorable from the L1 data availability. + * For this reason, the user may request the sequencer to publish the original bytecode and mark it as known. + * Or the user may compress the bytecode and publish it instead (fewer data onchain!). At the end of every L1 Batch + * we publish pubdata, part of which contains the state diffs that occurred within the batch. + */ +contract Compressor is ICompressor, ISystemContract { + using UnsafeBytesCalldata for bytes; + + /// @notice Verify the compressed bytecode and publish it on the L1. + /// @param _bytecode The original bytecode to be verified against. + /// @param _rawCompressedData The compressed bytecode in a format of: + /// - 2 bytes: the length of the dictionary + /// - N bytes: the dictionary + /// - M bytes: the encoded data + /// @dev The dictionary is a sequence of 8-byte chunks, each of them has the associated index. + /// @dev The encoded data is a sequence of 2-byte chunks, each of them is an index of the dictionary. + /// @dev The compression algorithm works as follows: + /// 1. The original bytecode is split into 8-byte chunks. + /// Since the bytecode size is always a multiple of 32, this is always possible. + /// 2. For each 8-byte chunk in the original bytecode: + /// * If the chunk is not already in the dictionary, it is added to the dictionary array. + /// * If the dictionary becomes overcrowded (2^16 + 1 elements), the compression process will fail. + /// * The 2-byte index of the chunk in the dictionary is added to the encoded data. + /// @dev Currently, the method may be called only from the bootloader because the server is not ready to publish bytecodes + /// in internal transactions. However, in the future, we will allow everyone to publish compressed bytecodes. + function publishCompressedBytecode( + bytes calldata _bytecode, + bytes calldata _rawCompressedData + ) external payable onlyCallFromBootloader returns (bytes32 bytecodeHash) { + unchecked { + (bytes calldata dictionary, bytes calldata encodedData) = _decodeRawBytecode(_rawCompressedData); + + require(dictionary.length % 8 == 0, "Dictionary length should be a multiple of 8"); + require(dictionary.length <= 2 ** 16 * 8, "Dictionary is too big"); + require( + encodedData.length * 4 == _bytecode.length, + "Encoded data length should be 4 times shorter than the original bytecode" + ); + + for (uint256 encodedDataPointer = 0; encodedDataPointer < encodedData.length; encodedDataPointer += 2) { + uint256 indexOfEncodedChunk = uint256(encodedData.readUint16(encodedDataPointer)) * 8; + require(indexOfEncodedChunk < dictionary.length, "Encoded chunk index is out of bounds"); + + uint64 encodedChunk = dictionary.readUint64(indexOfEncodedChunk); + uint64 realChunk = _bytecode.readUint64(encodedDataPointer * 4); + + require(encodedChunk == realChunk, "Encoded chunk does not match the original bytecode"); + } + } + + bytecodeHash = Utils.hashL2Bytecode(_bytecode); + L1_MESSENGER_CONTRACT.sendToL1(_rawCompressedData); + KNOWN_CODE_STORAGE_CONTRACT.markBytecodeAsPublished(bytecodeHash); + } + + /// @notice Verifies that the compression of state diffs has been done correctly for the {_stateDiffs} param. + /// @param _numberOfStateDiffs The number of state diffs being checked. + /// @param _enumerationIndexSize Number of bytes used to represent an enumeration index for repeated writes. + /// @param _stateDiffs Encoded full state diff structs. See the first dev comment below for encoding. + /// @param _compressedStateDiffs The compressed state diffs + /// @dev We don't verify that the size of {_stateDiffs} is equivalent to {_numberOfStateDiffs} * STATE_DIFF_ENTRY_SIZE since that check is + /// done within the L1Messenger calling contract. + /// @return stateDiffHash Hash of the encoded (uncompressed) state diffs to be committed to via system log. + /// @dev This check assumes that the ordering of state diffs are sorted by (address, key) for the encoded state diffs and + /// then the compressed are sorted the same but with all the initial writes coming before the repeated writes. + /// @dev state diff: [20bytes address][32bytes key][32bytes derived key][8bytes enum index][32bytes initial value][32bytes final value] + /// @dev The compression format: + /// - 2 bytes: number of initial writes + /// - N bytes initial writes + /// - 32 bytes derived key + /// - 1 byte metadata: + /// - first 5 bits: length in bytes of compressed value + /// - last 3 bits: operation + /// - 0 -> Nothing (32 bytes) + /// - 1 -> Add + /// - 2 -> Subtract + /// - 3 -> Transform (< 32 bytes) + /// - Len Bytes: Compressed Value + /// - M bytes repeated writes + /// - {_enumerationIndexSize} bytes for enumeration index + /// - 1 byte metadata: + /// - first 5 bits: length in bytes of compressed value + /// - last 3 bits: operation + /// - 0 -> Nothing (32 bytes) + /// - 1 -> Add + /// - 2 -> Subtract + /// - 3 -> Transform (< 32 bytes) + /// - Len Bytes: Compressed Value + function verifyCompressedStateDiffs( + uint256 _numberOfStateDiffs, + uint256 _enumerationIndexSize, + bytes calldata _stateDiffs, + bytes calldata _compressedStateDiffs + ) external payable onlyCallFrom(address(L1_MESSENGER_CONTRACT)) returns (bytes32 stateDiffHash) { + // We do not enforce the operator to use the optimal, i.e. the minimally possible _enumerationIndexSize. + // We do enforce however, that the _enumerationIndexSize is not larger than 8 bytes long, which is the + // maximal ever possible size for enumeration index. + require(_enumerationIndexSize <= MAX_ENUMERATION_INDEX_SIZE, "enumeration index size is too large"); + + uint256 numberOfInitialWrites = uint256(_compressedStateDiffs.readUint16(0)); + + uint256 stateDiffPtr = 2; + uint256 numInitialWritesProcessed = 0; + + // Process initial writes + for (uint256 i = 0; i < _numberOfStateDiffs * STATE_DIFF_ENTRY_SIZE; i += STATE_DIFF_ENTRY_SIZE) { + bytes calldata stateDiff = _stateDiffs[i:i + STATE_DIFF_ENTRY_SIZE]; + uint64 enumIndex = stateDiff.readUint64(84); + if (enumIndex != 0) { + // It is a repeated write, so we skip it. + continue; + } + + numInitialWritesProcessed++; + + bytes32 derivedKey = stateDiff.readBytes32(52); + uint256 initValue = stateDiff.readUint256(92); + uint256 finalValue = stateDiff.readUint256(124); + require(derivedKey == _compressedStateDiffs.readBytes32(stateDiffPtr), "iw: initial key mismatch"); + stateDiffPtr += 32; + + uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr])); + stateDiffPtr++; + uint8 operation = metadata & OPERATION_BITMASK; + uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; + _verifyValueCompression( + initValue, + finalValue, + operation, + _compressedStateDiffs[stateDiffPtr:stateDiffPtr + len] + ); + stateDiffPtr += len; + } + + require(numInitialWritesProcessed == numberOfInitialWrites, "Incorrect number of initial storage diffs"); + + // Process repeated writes + for (uint256 i = 0; i < _numberOfStateDiffs * STATE_DIFF_ENTRY_SIZE; i += STATE_DIFF_ENTRY_SIZE) { + bytes calldata stateDiff = _stateDiffs[i:i + STATE_DIFF_ENTRY_SIZE]; + uint64 enumIndex = stateDiff.readUint64(84); + if (enumIndex == 0) { + continue; + } + + uint256 initValue = stateDiff.readUint256(92); + uint256 finalValue = stateDiff.readUint256(124); + uint256 compressedEnumIndex = _sliceToUint256( + _compressedStateDiffs[stateDiffPtr:stateDiffPtr + _enumerationIndexSize] + ); + require(enumIndex == compressedEnumIndex, "rw: enum key mismatch"); + stateDiffPtr += _enumerationIndexSize; + + uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr])); + stateDiffPtr += 1; + uint8 operation = metadata & OPERATION_BITMASK; + uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; + _verifyValueCompression( + initValue, + finalValue, + operation, + _compressedStateDiffs[stateDiffPtr:stateDiffPtr + len] + ); + stateDiffPtr += len; + } + + require(stateDiffPtr == _compressedStateDiffs.length, "Extra data in _compressedStateDiffs"); + + stateDiffHash = EfficientCall.keccak(_stateDiffs); + } + + /// @notice Decode the raw compressed data into the dictionary and the encoded data. + /// @param _rawCompressedData The compressed bytecode in a format of: + /// - 2 bytes: the bytes length of the dictionary + /// - N bytes: the dictionary + /// - M bytes: the encoded data + function _decodeRawBytecode( + bytes calldata _rawCompressedData + ) internal pure returns (bytes calldata dictionary, bytes calldata encodedData) { + unchecked { + // The dictionary length can't be more than 2^16, so it fits into 2 bytes. + uint256 dictionaryLen = uint256(_rawCompressedData.readUint16(0)); + dictionary = _rawCompressedData[2:2 + dictionaryLen * 8]; + encodedData = _rawCompressedData[2 + dictionaryLen * 8:]; + } + } + + /// @notice Verify value compression was done correct given initial value, final value, operation, and compressed value + /// @param _initialValue Previous value of key/enumeration index. + /// @param _finalValue Updated value of key/enumeration index. + /// @param _operation The operation that was performed on value. + /// @param _compressedValue The slice of calldata with compressed value either representing the final + /// value or difference between initial and final value. It should be of arbitrary length less than or equal to 32 bytes. + /// @dev It is the responsibility of the caller of this function to ensure that the `_compressedValue` has length no longer than 32 bytes. + /// @dev Operation id mapping: + /// 0 -> Nothing (32 bytes) + /// 1 -> Add + /// 2 -> Subtract + /// 3 -> Transform (< 32 bytes) + function _verifyValueCompression( + uint256 _initialValue, + uint256 _finalValue, + uint256 _operation, + bytes calldata _compressedValue + ) internal pure { + uint256 convertedValue = _sliceToUint256(_compressedValue); + + unchecked { + if (_operation == 0 || _operation == 3) { + require(convertedValue == _finalValue, "transform or no compression: compressed and final mismatch"); + } else if (_operation == 1) { + require( + _initialValue + convertedValue == _finalValue, + "add: initial plus converted not equal to final" + ); + } else if (_operation == 2) { + require( + _initialValue - convertedValue == _finalValue, + "sub: initial minus converted not equal to final" + ); + } else { + revert("unsupported operation"); + } + } + } + + /// @notice Converts a calldata slice into uint256. It is the responsibility of the caller to ensure that + /// the _calldataSlice has length no longer than 32 bytes + /// @param _calldataSlice The calldata slice to convert to uint256 + /// @return number The uint256 representation of the calldata slice + function _sliceToUint256(bytes calldata _calldataSlice) internal pure returns (uint256 number) { + number = uint256(bytes32(_calldataSlice)); + number >>= (256 - (_calldataSlice.length * 8)); + } +} diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol new file mode 100644 index 000000000..4eeca364a --- /dev/null +++ b/system-contracts/contracts/Constants.sol @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {IAccountCodeStorage} from "./interfaces/IAccountCodeStorage.sol"; +import {INonceHolder} from "./interfaces/INonceHolder.sol"; +import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; +import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol"; +import {IImmutableSimulator} from "./interfaces/IImmutableSimulator.sol"; +import {IEthToken} from "./interfaces/IEthToken.sol"; +import {IL1Messenger} from "./interfaces/IL1Messenger.sol"; +import {ISystemContext} from "./interfaces/ISystemContext.sol"; +import {ICompressor} from "./interfaces/ICompressor.sol"; +import {IComplexUpgrader} from "./interfaces/IComplexUpgrader.sol"; +import {IBootloaderUtilities} from "./interfaces/IBootloaderUtilities.sol"; + +/// @dev All the system contracts introduced by zkSync have their addresses +/// started from 2^15 in order to avoid collision with Ethereum precompiles. +uint160 constant SYSTEM_CONTRACTS_OFFSET = {{SYSTEM_CONTRACTS_OFFSET}}; // 2^15 + +/// @dev All the system contracts must be located in the kernel space, +/// i.e. their addresses must be below 2^16. +uint160 constant MAX_SYSTEM_CONTRACT_ADDRESS = 0xffff; // 2^16 - 1 + +address constant ECRECOVER_SYSTEM_CONTRACT = address(0x01); +address constant SHA256_SYSTEM_CONTRACT = address(0x02); +address constant ECADD_SYSTEM_CONTRACT = address(0x06); +address constant ECMUL_SYSTEM_CONTRACT = address(0x07); + +/// @dev The maximal possible address of an L1-like precompie. These precompiles maintain the following properties: +/// - Their extcodehash is EMPTY_STRING_KECCAK +/// - Their extcodesize is 0 despite having a bytecode formally deployed there. +uint256 constant CURRENT_MAX_PRECOMPILE_ADDRESS = 0xff; + +address payable constant BOOTLOADER_FORMAL_ADDRESS = payable(address(SYSTEM_CONTRACTS_OFFSET + 0x01)); +IAccountCodeStorage constant ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT = IAccountCodeStorage( + address(SYSTEM_CONTRACTS_OFFSET + 0x02) +); +INonceHolder constant NONCE_HOLDER_SYSTEM_CONTRACT = INonceHolder(address(SYSTEM_CONTRACTS_OFFSET + 0x03)); +IKnownCodesStorage constant KNOWN_CODE_STORAGE_CONTRACT = IKnownCodesStorage(address(SYSTEM_CONTRACTS_OFFSET + 0x04)); +IImmutableSimulator constant IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT = IImmutableSimulator( + address(SYSTEM_CONTRACTS_OFFSET + 0x05) +); +IContractDeployer constant DEPLOYER_SYSTEM_CONTRACT = IContractDeployer(address(SYSTEM_CONTRACTS_OFFSET + 0x06)); + +// A contract that is allowed to deploy any codehash +// on any address. To be used only during an upgrade. +address constant FORCE_DEPLOYER = address(SYSTEM_CONTRACTS_OFFSET + 0x07); +IL1Messenger constant L1_MESSENGER_CONTRACT = IL1Messenger(address(SYSTEM_CONTRACTS_OFFSET + 0x08)); +address constant MSG_VALUE_SYSTEM_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x09); + +IEthToken constant ETH_TOKEN_SYSTEM_CONTRACT = IEthToken(address(SYSTEM_CONTRACTS_OFFSET + 0x0a)); + +// Hardcoded because even for tests we should keep the address. (Instead `SYSTEM_CONTRACTS_OFFSET + 0x10`) +// Precompile call depends on it. +// And we don't want to mock this contract. +address constant KECCAK256_SYSTEM_CONTRACT = address(0x8010); + +ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(payable(address(SYSTEM_CONTRACTS_OFFSET + 0x0b))); + +IBootloaderUtilities constant BOOTLOADER_UTILITIES = IBootloaderUtilities(address(SYSTEM_CONTRACTS_OFFSET + 0x0c)); + +// It will be a different value for tests, while shouldn't. But for now, this constant is not used by other contracts, so that's fine. +address constant EVENT_WRITER_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x0d); + +ICompressor constant COMPRESSOR_CONTRACT = ICompressor(address(SYSTEM_CONTRACTS_OFFSET + 0x0e)); + +IComplexUpgrader constant COMPLEX_UPGRADER_CONTRACT = IComplexUpgrader(address(SYSTEM_CONTRACTS_OFFSET + 0x0f)); + +/// @dev If the bitwise AND of the extraAbi[2] param when calling the MSG_VALUE_SIMULATOR +/// is non-zero, the call will be assumed to be a system one. +uint256 constant MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT = 1; + +/// @dev The maximal msg.value that context can have +uint256 constant MAX_MSG_VALUE = 2 ** 128 - 1; + +/// @dev Prefix used during derivation of account addresses using CREATE2 +/// @dev keccak256("zksyncCreate2") +bytes32 constant CREATE2_PREFIX = 0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494; +/// @dev Prefix used during derivation of account addresses using CREATE +/// @dev keccak256("zksyncCreate") +bytes32 constant CREATE_PREFIX = 0x63bae3a9951d38e8a3fbb7b70909afc1200610fc5bc55ade242f815974674f23; + +/// @dev Each state diff consists of 156 bytes of actual data and 116 bytes of unused padding, needed for circuit efficiency. +uint256 constant STATE_DIFF_ENTRY_SIZE = 272; + +/// @dev While the "real" amount of pubdata that can be sent rarely exceeds the 110k - 120k, it is better to +/// allow the operator to provide any reasonably large value in order to avoid unneeded constraints on the operator. +uint256 constant MAX_ALLOWED_PUBDATA_PER_BATCH = 520000; + +enum SystemLogKey { + L2_TO_L1_LOGS_TREE_ROOT_KEY, + TOTAL_L2_TO_L1_PUBDATA_KEY, + STATE_DIFF_HASH_KEY, + PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY, + PREV_BATCH_HASH_KEY, + CHAINED_PRIORITY_TXN_HASH_KEY, + NUMBER_OF_LAYER_1_TXS_KEY, + EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY +} + +/// @dev The number of leaves in the L2->L1 log Merkle tree. +/// While formally a tree of any length is acceptable, the node supports only a constant length of 2048 leaves. +uint256 constant L2_TO_L1_LOGS_MERKLE_TREE_LEAVES = 2048; + +/// @dev The length of the derived key in bytes inside compressed state diffs. +uint256 constant DERIVED_KEY_LENGTH = 32; +/// @dev The length of the enum index in bytes inside compressed state diffs. +uint256 constant ENUM_INDEX_LENGTH = 8; +/// @dev The length of value in bytes inside compressed state diffs. +uint256 constant VALUE_LENGTH = 32; + +/// @dev The length of the compressed initial storage write in bytes. +uint256 constant COMPRESSED_INITIAL_WRITE_SIZE = DERIVED_KEY_LENGTH + VALUE_LENGTH; +/// @dev The length of the compressed repeated storage write in bytes. +uint256 constant COMPRESSED_REPEATED_WRITE_SIZE = ENUM_INDEX_LENGTH + VALUE_LENGTH; + +/// @dev The position from which the initial writes start in the compressed state diffs. +uint256 constant INITIAL_WRITE_STARTING_POSITION = 4; + +/// @dev Each storage diffs consists of the following elements: +/// [20bytes address][32bytes key][32bytes derived key][8bytes enum index][32bytes initial value][32bytes final value] +/// @dev The offset of the deriived key in a storage diff. +uint256 constant STATE_DIFF_DERIVED_KEY_OFFSET = 52; +/// @dev The offset of the enum index in a storage diff. +uint256 constant STATE_DIFF_ENUM_INDEX_OFFSET = 84; +/// @dev The offset of the final value in a storage diff. +uint256 constant STATE_DIFF_FINAL_VALUE_OFFSET = 124; diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol new file mode 100644 index 000000000..50af97421 --- /dev/null +++ b/system-contracts/contracts/ContractDeployer.sol @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {ImmutableData} from "./interfaces/IImmutableSimulator.sol"; +import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; +import {CREATE2_PREFIX, CREATE_PREFIX, NONCE_HOLDER_SYSTEM_CONTRACT, ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT, FORCE_DEPLOYER, MAX_SYSTEM_CONTRACT_ADDRESS, KNOWN_CODE_STORAGE_CONTRACT, ETH_TOKEN_SYSTEM_CONTRACT, IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT, COMPLEX_UPGRADER_CONTRACT, KECCAK256_SYSTEM_CONTRACT} from "./Constants.sol"; + +import {Utils} from "./libraries/Utils.sol"; +import {EfficientCall} from "./libraries/EfficientCall.sol"; +import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice System smart contract that is responsible for deploying other smart contracts on zkSync. + * @dev The contract is responsible for generating the address of the deployed smart contract, + * incrementing the deployment nonce and making sure that the constructor is never called twice in a contract. + * Note, contracts with bytecode that have already been published to L1 once + * do not need to be published anymore. + */ +contract ContractDeployer is IContractDeployer, ISystemContract { + /// @notice Information about an account contract. + /// @dev For EOA and simple contracts (i.e. not accounts) this value is 0. + mapping(address => AccountInfo) internal accountInfo; + + modifier onlySelf() { + require(msg.sender == address(this), "Callable only by self"); + _; + } + + /// @notice Returns information about a certain account. + function getAccountInfo(address _address) external view returns (AccountInfo memory info) { + return accountInfo[_address]; + } + + /// @notice Returns the account abstraction version if `_address` is a deployed contract. + /// Returns the latest supported account abstraction version if `_address` is an EOA. + function extendedAccountVersion(address _address) public view returns (AccountAbstractionVersion) { + AccountInfo memory info = accountInfo[_address]; + if (info.supportedAAVersion != AccountAbstractionVersion.None) { + return info.supportedAAVersion; + } + + // It is an EOA, it is still an account. + if ( + _address > address(MAX_SYSTEM_CONTRACT_ADDRESS) && + ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getRawCodeHash(_address) == 0 + ) { + return AccountAbstractionVersion.Version1; + } + + return AccountAbstractionVersion.None; + } + + /// @notice Stores the new account information + function _storeAccountInfo(address _address, AccountInfo memory _newInfo) internal { + accountInfo[_address] = _newInfo; + } + + /// @notice Update the used version of the account. + /// @param _version The new version of the AA protocol to use. + /// @dev Note that it allows changes from account to non-account and vice versa. + function updateAccountVersion(AccountAbstractionVersion _version) external onlySystemCall { + accountInfo[msg.sender].supportedAAVersion = _version; + + emit AccountVersionUpdated(msg.sender, _version); + } + + /// @notice Updates the nonce ordering of the account. Currently, + /// it only allows changes from sequential to arbitrary ordering. + /// @param _nonceOrdering The new nonce ordering to use. + function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external onlySystemCall { + AccountInfo memory currentInfo = accountInfo[msg.sender]; + + require( + _nonceOrdering == AccountNonceOrdering.Arbitrary && + currentInfo.nonceOrdering == AccountNonceOrdering.Sequential, + "It is only possible to change from sequential to arbitrary ordering" + ); + + currentInfo.nonceOrdering = _nonceOrdering; + _storeAccountInfo(msg.sender, currentInfo); + + emit AccountNonceOrderingUpdated(msg.sender, _nonceOrdering); + } + + /// @notice Calculates the address of a deployed contract via create2 + /// @param _sender The account that deploys the contract. + /// @param _bytecodeHash The correctly formatted hash of the bytecode. + /// @param _salt The create2 salt. + /// @param _input The constructor data. + /// @return newAddress The derived address of the account. + function getNewAddressCreate2( + address _sender, + bytes32 _bytecodeHash, + bytes32 _salt, + bytes calldata _input + ) public view override returns (address newAddress) { + // No collision is possible with the Ethereum's CREATE2, since + // the prefix begins with 0x20.... + bytes32 constructorInputHash = EfficientCall.keccak(_input); + + bytes32 hash = keccak256( + bytes.concat(CREATE2_PREFIX, bytes32(uint256(uint160(_sender))), _salt, _bytecodeHash, constructorInputHash) + ); + + newAddress = address(uint160(uint256(hash))); + } + + /// @notice Calculates the address of a deployed contract via create + /// @param _sender The account that deploys the contract. + /// @param _senderNonce The deploy nonce of the sender's account. + function getNewAddressCreate( + address _sender, + uint256 _senderNonce + ) public pure override returns (address newAddress) { + // No collision is possible with the Ethereum's CREATE, since + // the prefix begins with 0x63.... + bytes32 hash = keccak256( + bytes.concat(CREATE_PREFIX, bytes32(uint256(uint160(_sender))), bytes32(_senderNonce)) + ); + + newAddress = address(uint160(uint256(hash))); + } + + /// @notice Deploys a contract with similar address derivation rules to the EVM's `CREATE2` opcode. + /// @param _salt The CREATE2 salt + /// @param _bytecodeHash The correctly formatted hash of the bytecode. + /// @param _input The constructor calldata + /// @dev In case of a revert, the zero address should be returned. + function create2( + bytes32 _salt, + bytes32 _bytecodeHash, + bytes calldata _input + ) external payable override returns (address) { + return create2Account(_salt, _bytecodeHash, _input, AccountAbstractionVersion.None); + } + + /// @notice Deploys a contract with similar address derivation rules to the EVM's `CREATE` opcode. + /// @param _bytecodeHash The correctly formatted hash of the bytecode. + /// @param _input The constructor calldata + /// @dev This method also accepts nonce as one of its parameters. + /// It is not used anywhere and it needed simply for the consistency for the compiler + /// @dev In case of a revert, the zero address should be returned. + /// Note: this method may be callable only in system mode, + /// that is checked in the `createAccount` by `onlySystemCall` modifier. + function create( + bytes32 _salt, + bytes32 _bytecodeHash, + bytes calldata _input + ) external payable override returns (address) { + return createAccount(_salt, _bytecodeHash, _input, AccountAbstractionVersion.None); + } + + /// @notice Deploys a contract account with similar address derivation rules to the EVM's `CREATE2` opcode. + /// @param _salt The CREATE2 salt + /// @param _bytecodeHash The correctly formatted hash of the bytecode. + /// @param _input The constructor calldata. + /// @param _aaVersion The account abstraction version to use. + /// @dev In case of a revert, the zero address should be returned. + /// Note: this method may be callable only in system mode, + /// that is checked in the `createAccount` by `onlySystemCall` modifier. + function create2Account( + bytes32 _salt, + bytes32 _bytecodeHash, + bytes calldata _input, + AccountAbstractionVersion _aaVersion + ) public payable override onlySystemCall returns (address) { + NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender); + address newAddress = getNewAddressCreate2(msg.sender, _bytecodeHash, _salt, _input); + + _nonSystemDeployOnAddress(_bytecodeHash, newAddress, _aaVersion, _input); + + return newAddress; + } + + /// @notice Deploys a contract account with similar address derivation rules to the EVM's `CREATE` opcode. + /// @param _bytecodeHash The correctly formatted hash of the bytecode. + /// @param _input The constructor calldata. + /// @param _aaVersion The account abstraction version to use. + /// @dev This method also accepts salt as one of its parameters. + /// It is not used anywhere and it needed simply for the consistency for the compiler + /// @dev In case of a revert, the zero address should be returned. + function createAccount( + bytes32, // salt + bytes32 _bytecodeHash, + bytes calldata _input, + AccountAbstractionVersion _aaVersion + ) public payable override onlySystemCall returns (address) { + uint256 senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender); + address newAddress = getNewAddressCreate(msg.sender, senderNonce); + + _nonSystemDeployOnAddress(_bytecodeHash, newAddress, _aaVersion, _input); + + return newAddress; + } + + /// @notice A struct that describes a forced deployment on an address + struct ForceDeployment { + // The bytecode hash to put on an address + bytes32 bytecodeHash; + // The address on which to deploy the bytecodehash to + address newAddress; + // Whether to run the constructor on the force deployment + bool callConstructor; + // The value with which to initialize a contract + uint256 value; + // The constructor calldata + bytes input; + } + + /// @notice The method that can be used to forcefully deploy a contract. + /// @param _deployment Information about the forced deployment. + /// @param _sender The `msg.sender` inside the constructor call. + function forceDeployOnAddress(ForceDeployment calldata _deployment, address _sender) external payable onlySelf { + _ensureBytecodeIsKnown(_deployment.bytecodeHash); + + // Since the `forceDeployOnAddress` function is called only during upgrades, the Governance is trusted to correctly select + // the addresses to deploy the new bytecodes to and to assess whether overriding the AccountInfo for the "force-deployed" + // contract is acceptable. + AccountInfo memory newAccountInfo; + newAccountInfo.supportedAAVersion = AccountAbstractionVersion.None; + // Accounts have sequential nonces by default. + newAccountInfo.nonceOrdering = AccountNonceOrdering.Sequential; + _storeAccountInfo(_deployment.newAddress, newAccountInfo); + + _constructContract( + _sender, + _deployment.newAddress, + _deployment.bytecodeHash, + _deployment.input, + false, + _deployment.callConstructor + ); + } + + /// @notice The method that is temporarily needed to upgrade the Keccak256 precompile. It is to be removed in the + /// future. Unlike a normal forced deployment, it does not update account information as it requires updating a + /// mapping, and so requires Keccak256 precompile to work already. + /// @dev This method expects the sender (FORCE_DEPLOYER) to provide the correct bytecode hash for the Keccak256 + /// precompile. + function forceDeployKeccak256(bytes32 _keccak256BytecodeHash) external payable onlyCallFrom(FORCE_DEPLOYER) { + _ensureBytecodeIsKnown(_keccak256BytecodeHash); + _constructContract( + msg.sender, + address(KECCAK256_SYSTEM_CONTRACT), + _keccak256BytecodeHash, + msg.data[0:0], + false, + false + ); + } + + /// @notice This method is to be used only during an upgrade to set bytecodes on specific addresses. + /// @dev We do not require `onlySystemCall` here, since the method is accessible only + /// by `FORCE_DEPLOYER`. + function forceDeployOnAddresses(ForceDeployment[] calldata _deployments) external payable { + require( + msg.sender == FORCE_DEPLOYER || msg.sender == address(COMPLEX_UPGRADER_CONTRACT), + "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT" + ); + + uint256 deploymentsLength = _deployments.length; + // We need to ensure that the `value` provided by the call is enough to provide `value` + // for all of the deployments + uint256 sumOfValues = 0; + for (uint256 i = 0; i < deploymentsLength; ++i) { + sumOfValues += _deployments[i].value; + } + require(msg.value == sumOfValues, "`value` provided is not equal to the combined `value`s of deployments"); + + for (uint256 i = 0; i < deploymentsLength; ++i) { + this.forceDeployOnAddress{value: _deployments[i].value}(_deployments[i], msg.sender); + } + } + + function _nonSystemDeployOnAddress( + bytes32 _bytecodeHash, + address _newAddress, + AccountAbstractionVersion _aaVersion, + bytes calldata _input + ) internal { + require(_bytecodeHash != bytes32(0x0), "BytecodeHash cannot be zero"); + require(uint160(_newAddress) > MAX_SYSTEM_CONTRACT_ADDRESS, "Can not deploy contracts in kernel space"); + + // We do not allow deploying twice on the same address. + require( + ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0, + "Code hash is non-zero" + ); + // Do not allow deploying contracts to default accounts that have already executed transactions. + require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x00, "Account is occupied"); + + _performDeployOnAddress(_bytecodeHash, _newAddress, _aaVersion, _input); + } + + /// @notice Deploy a certain bytecode on the address. + /// @param _bytecodeHash The correctly formatted hash of the bytecode. + /// @param _newAddress The address of the contract to be deployed. + /// @param _aaVersion The version of the account abstraction protocol to use. + /// @param _input The constructor calldata. + function _performDeployOnAddress( + bytes32 _bytecodeHash, + address _newAddress, + AccountAbstractionVersion _aaVersion, + bytes calldata _input + ) internal { + _ensureBytecodeIsKnown(_bytecodeHash); + + AccountInfo memory newAccountInfo; + newAccountInfo.supportedAAVersion = _aaVersion; + // Accounts have sequential nonces by default. + newAccountInfo.nonceOrdering = AccountNonceOrdering.Sequential; + _storeAccountInfo(_newAddress, newAccountInfo); + + _constructContract(msg.sender, _newAddress, _bytecodeHash, _input, false, true); + } + + /// @notice Check that bytecode hash is marked as known on the `KnownCodeStorage` system contracts + function _ensureBytecodeIsKnown(bytes32 _bytecodeHash) internal view { + uint256 knownCodeMarker = KNOWN_CODE_STORAGE_CONTRACT.getMarker(_bytecodeHash); + require(knownCodeMarker > 0, "The code hash is not known"); + } + + /// @notice Ensures that the _newAddress and assigns a new contract hash to it + /// @param _newAddress The address of the deployed contract + /// @param _bytecodeHash The correctly formatted hash of the bytecode. + function _storeConstructingByteCodeHashOnAddress(address _newAddress, bytes32 _bytecodeHash) internal { + // Set the "isConstructor" flag to the bytecode hash + bytes32 constructingBytecodeHash = Utils.constructingBytecodeHash(_bytecodeHash); + ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.storeAccountConstructingCodeHash(_newAddress, constructingBytecodeHash); + } + + /// @notice Transfers the `msg.value` ETH to the deployed account & invokes its constructor. + /// This function must revert in case the deployment fails. + /// @param _sender The msg.sender to be used in the constructor + /// @param _newAddress The address of the deployed contract + /// @param _input The constructor calldata + /// @param _isSystem Whether the call should be a system call (could be possibly required in the future). + function _constructContract( + address _sender, + address _newAddress, + bytes32 _bytecodeHash, + bytes calldata _input, + bool _isSystem, + bool _callConstructor + ) internal { + uint256 value = msg.value; + if (_callConstructor) { + // 1. Transfer the balance to the new address on the constructor call. + if (value > 0) { + ETH_TOKEN_SYSTEM_CONTRACT.transferFromTo(address(this), _newAddress, value); + } + // 2. Set the constructed code hash on the account + _storeConstructingByteCodeHashOnAddress(_newAddress, _bytecodeHash); + + // 3. Call the constructor on behalf of the account + if (value > 0) { + // Safe to cast value, because `msg.value` <= `uint128.max` due to `MessageValueSimulator` invariant + SystemContractHelper.setValueForNextFarCall(uint128(value)); + } + bytes memory returnData = EfficientCall.mimicCall(gasleft(), _newAddress, _input, _sender, true, _isSystem); + // 4. Mark bytecode hash as constructed + ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.markAccountCodeHashAsConstructed(_newAddress); + // 5. Set the contract immutables + ImmutableData[] memory immutables = abi.decode(returnData, (ImmutableData[])); + IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT.setImmutables(_newAddress, immutables); + } else { + require(value == 0, "The value must be zero if we do not call the constructor"); + // If we do not call the constructor, we need to set the constructed code hash. + ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.storeAccountConstructedCodeHash(_newAddress, _bytecodeHash); + } + + emit ContractDeployed(_sender, _bytecodeHash, _newAddress); + } +} diff --git a/system-contracts/contracts/DefaultAccount.sol b/system-contracts/contracts/DefaultAccount.sol new file mode 100644 index 000000000..2257269d6 --- /dev/null +++ b/system-contracts/contracts/DefaultAccount.sol @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./interfaces/IAccount.sol"; +import "./libraries/TransactionHelper.sol"; +import "./libraries/SystemContractHelper.sol"; +import "./libraries/EfficientCall.sol"; +import {BOOTLOADER_FORMAL_ADDRESS, NONCE_HOLDER_SYSTEM_CONTRACT, DEPLOYER_SYSTEM_CONTRACT, INonceHolder} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The default implementation of account. + * @dev The bytecode of the contract is set by default for all addresses for which no other bytecodes are deployed. + * @notice If the caller is not a bootloader always returns empty data on call, just like EOA does. + * @notice If it is delegate called always returns empty data, just like EOA does. + */ +contract DefaultAccount is IAccount { + using TransactionHelper for *; + + /** + * @dev Simulate the behavior of the EOA if the caller is not the bootloader. + * Essentially, for all non-bootloader callers halt the execution with empty return data. + * If all functions will use this modifier AND the contract will implement an empty payable fallback() + * then the contract will be indistinguishable from the EOA when called. + */ + modifier ignoreNonBootloader() { + if (msg.sender != BOOTLOADER_FORMAL_ADDRESS) { + // If function was called outside of the bootloader, behave like an EOA. + assembly { + return(0, 0) + } + } + // Continue execution if called from the bootloader. + _; + } + + /** + * @dev Simulate the behavior of the EOA if it is called via `delegatecall`. + * Thus, the default account on a delegate call behaves the same as EOA on Ethereum. + * If all functions will use this modifier AND the contract will implement an empty payable fallback() + * then the contract will be indistinguishable from the EOA when called. + */ + modifier ignoreInDelegateCall() { + address codeAddress = SystemContractHelper.getCodeAddress(); + if (codeAddress != address(this)) { + // If the function was delegate called, behave like an EOA. + assembly { + return(0, 0) + } + } + + // Continue execution if not delegate called. + _; + } + + /// @notice Validates the transaction & increments nonce. + /// @dev The transaction is considered accepted by the account if + /// the call to this function by the bootloader does not revert + /// and the nonce has been set as used. + /// @param _suggestedSignedHash The suggested hash of the transaction to be signed by the user. + /// This is the hash that is signed by the EOA by default. + /// @param _transaction The transaction structure itself. + /// @dev Besides the params above, it also accepts unused first paramter "_txHash", which + /// is the unique (canonical) hash of the transaction. + function validateTransaction( + bytes32, // _txHash + bytes32 _suggestedSignedHash, + Transaction calldata _transaction + ) external payable override ignoreNonBootloader ignoreInDelegateCall returns (bytes4 magic) { + magic = _validateTransaction(_suggestedSignedHash, _transaction); + } + + /// @notice Inner method for validating transaction and increasing the nonce + /// @param _suggestedSignedHash The hash of the transaction signed by the EOA + /// @param _transaction The transaction. + function _validateTransaction( + bytes32 _suggestedSignedHash, + Transaction calldata _transaction + ) internal returns (bytes4 magic) { + // Note, that nonce holder can only be called with "isSystem" flag. + SystemContractsCaller.systemCallWithPropagatedRevert( + uint32(gasleft()), + address(NONCE_HOLDER_SYSTEM_CONTRACT), + 0, + abi.encodeCall(INonceHolder.incrementMinNonceIfEquals, (_transaction.nonce)) + ); + + // Even though for the transaction types present in the system right now, + // we always provide the suggested signed hash, this should not be + // always expected. In case the bootloader has no clue what the default hash + // is, the bytes32(0) will be supplied. + bytes32 txHash = _suggestedSignedHash != bytes32(0) ? _suggestedSignedHash : _transaction.encodeHash(); + + // The fact there is are enough balance for the account + // should be checked explicitly to prevent user paying for fee for a + // transaction that wouldn't be included on Ethereum. + uint256 totalRequiredBalance = _transaction.totalRequiredBalance(); + require(totalRequiredBalance <= address(this).balance, "Not enough balance for fee + value"); + + if (_isValidSignature(txHash, _transaction.signature)) { + magic = ACCOUNT_VALIDATION_SUCCESS_MAGIC; + } + } + + /// @notice Method called by the bootloader to execute the transaction. + /// @param _transaction The transaction to execute. + /// @dev It also accepts unused _txHash and _suggestedSignedHash parameters: + /// the unique (canonical) hash of the transaction and the suggested signed + /// hash of the transaction. + function executeTransaction( + bytes32, // _txHash + bytes32, // _suggestedSignedHash + Transaction calldata _transaction + ) external payable override ignoreNonBootloader ignoreInDelegateCall { + _execute(_transaction); + } + + /// @notice Method that should be used to initiate a transaction from this account by an external call. + /// @dev The custom account is supposed to implement this method to initiate a transaction on behalf + /// of the account via L1 -> L2 communication. However, the default account can initiate a transaction + /// from L1, so we formally implement the interface method, but it doesn't execute any logic. + /// @param _transaction The transaction to execute. + function executeTransactionFromOutside(Transaction calldata _transaction) external payable override { + // Behave the same as for fallback/receive, just execute nothing, returns nothing + } + + /// @notice Inner method for executing a transaction. + /// @param _transaction The transaction to execute. + function _execute(Transaction calldata _transaction) internal { + address to = address(uint160(_transaction.to)); + uint128 value = Utils.safeCastToU128(_transaction.value); + bytes calldata data = _transaction.data; + uint32 gas = Utils.safeCastToU32(gasleft()); + + // Note, that the deployment method from the deployer contract can only be called with a "systemCall" flag. + bool isSystemCall; + if (to == address(DEPLOYER_SYSTEM_CONTRACT) && data.length >= 4) { + bytes4 selector = bytes4(data[:4]); + // Check that called function is the deployment method, + // the others deployer method is not supposed to be called from the default account. + isSystemCall = + selector == DEPLOYER_SYSTEM_CONTRACT.create.selector || + selector == DEPLOYER_SYSTEM_CONTRACT.create2.selector || + selector == DEPLOYER_SYSTEM_CONTRACT.createAccount.selector || + selector == DEPLOYER_SYSTEM_CONTRACT.create2Account.selector; + } + bool success = EfficientCall.rawCall(gas, to, value, data, isSystemCall); + if (!success) { + EfficientCall.propagateRevert(); + } + } + + /// @notice Validation that the ECDSA signature of the transaction is correct. + /// @param _hash The hash of the transaction to be signed. + /// @param _signature The signature of the transaction. + /// @return EIP1271_SUCCESS_RETURN_VALUE if the signaure is correct. It reverts otherwise. + function _isValidSignature(bytes32 _hash, bytes memory _signature) internal view returns (bool) { + require(_signature.length == 65, "Signature length is incorrect"); + uint8 v; + bytes32 r; + bytes32 s; + // Signature loading code + // we jump 32 (0x20) as the first slot of bytes contains the length + // we jump 65 (0x41) per signature + // for v we load 32 bytes ending with v (the first 31 come from s) then apply a mask + assembly { + r := mload(add(_signature, 0x20)) + s := mload(add(_signature, 0x40)) + v := and(mload(add(_signature, 0x41)), 0xff) + } + require(v == 27 || v == 28, "v is neither 27 nor 28"); + + // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature + // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines + // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most + // signatures from current libraries generate a unique signature with an s-value in the lower half order. + // + // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value + // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or + // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept + // these malleable signatures as well. + require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "Invalid s"); + + address recoveredAddress = ecrecover(_hash, v, r, s); + + return recoveredAddress == address(this) && recoveredAddress != address(0); + } + + /// @notice Method for paying the bootloader for the transaction. + /// @param _transaction The transaction for which the fee is paid. + /// @dev It also accepts unused _txHash and _suggestedSignedHash parameters: + /// the unique (canonical) hash of the transaction and the suggested signed + /// hash of the transaction. + function payForTransaction( + bytes32, // _txHash + bytes32, // _suggestedSignedHash + Transaction calldata _transaction + ) external payable ignoreNonBootloader ignoreInDelegateCall { + bool success = _transaction.payToTheBootloader(); + require(success, "Failed to pay the fee to the operator"); + } + + /// @notice Method, where the user should prepare for the transaction to be + /// paid for by a paymaster. + /// @dev Here, the account should set the allowance for the smart contracts + /// @param _transaction The transaction. + /// @dev It also accepts unused _txHash and _suggestedSignedHash parameters: + /// the unique (canonical) hash of the transaction and the suggested signed + /// hash of the transaction. + function prepareForPaymaster( + bytes32, // _txHash + bytes32, // _suggestedSignedHash + Transaction calldata _transaction + ) external payable ignoreNonBootloader ignoreInDelegateCall { + _transaction.processPaymasterInput(); + } + + fallback() external payable ignoreInDelegateCall { + // fallback of default account shouldn't be called by bootloader under no circumstances + assert(msg.sender != BOOTLOADER_FORMAL_ADDRESS); + + // If the contract is called directly, behave like an EOA + } + + receive() external payable { + // If the contract is called directly, behave like an EOA + } +} diff --git a/system-contracts/contracts/EmptyContract.sol b/system-contracts/contracts/EmptyContract.sol new file mode 100644 index 000000000..f0304beb4 --- /dev/null +++ b/system-contracts/contracts/EmptyContract.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The "empty" contract that is put into some system contracts by default. + * @dev The bytecode of the contract is set by default for all addresses for which no other bytecodes are deployed. + */ +contract EmptyContract { + fallback() external payable {} + + receive() external payable {} +} diff --git a/system-contracts/contracts/EventWriter.yul b/system-contracts/contracts/EventWriter.yul new file mode 100644 index 000000000..4cd4a3814 --- /dev/null +++ b/system-contracts/contracts/EventWriter.yul @@ -0,0 +1,170 @@ +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The contract responsible for decoding and writing events using low-level instructions. + * @dev The metadata and topics are passed via registers, and the first accessible register contains their number. + * The rest of the data is passed via calldata without copying. + */ +object "EventWriter" { + code { + return(0, 0) + } + object "EventWriter_deployed" { + code { + //////////////////////////////////////////////////////////////// + // HELPER FUNCTIONS + //////////////////////////////////////////////////////////////// + + // For the documentation of the helper functions, please refer to + // the corresponding functions in the SystemContractHelper.sol. + + /// @notice Returns the 0-th extraAbiParam for the current call. + /// @dev It is equal to the value of the 2-th register at the start of the call. + function getExtraAbiData_0() -> extraAbiData { + extraAbiData := verbatim_0i_1o("get_global::extra_abi_data_0") + } + + /// @notice Returns the 1-th extraAbiParam for the current call. + /// @dev It is equal to the value of the 3-th register at the start of the call. + function getExtraAbiData_1() -> extraAbiData { + extraAbiData := verbatim_0i_1o("get_global::extra_abi_data_1") + } + + /// @notice Returns the 2-th extraAbiParam for the current call. + /// @dev It is equal to the value of the 4-th register at the start of the call. + function getExtraAbiData_2() -> extraAbiData { + extraAbiData := verbatim_0i_1o("get_global::extra_abi_data_2") + } + + /// @notice Returns the 3-th extraAbiParam for the current call. + /// @dev It is equal to the value of the 5-th register at the start of the call. + function getExtraAbiData_3() -> extraAbiData { + extraAbiData := verbatim_0i_1o("get_global::extra_abi_data_3") + } + + /// @notice Returns the 4-th extraAbiParam for the current call. + /// @dev It is equal to the value of the 6-th register at the start of the call. + function getExtraAbiData_4() -> extraAbiData { + extraAbiData := verbatim_0i_1o("get_global::extra_abi_data_4") + } + + /// @notice Returns the call flags for the current call. + /// @dev Call flags is the value of the first register at the start of the call. + /// @dev The zero bit of the callFlags indicates whether the call is + /// a constructor call. The first bit of the callFlags indicates whether + /// the call is a system one. + function getCallFlags() -> ret { + ret := verbatim_0i_1o("get_global::call_flags") + } + + /// @notice Initialize a new event + /// @param initializer The event initializing value + /// @param value1 The first topic or data chunk. + function eventInitialize(initializer, value1) { + verbatim_2i_0o("event_initialize", initializer, value1) + } + + /// @notice Continue writing the previously initialized event. + /// @param value1 The first topic or data chunk. + /// @param value2 The second topic or data chunk. + function eventWrite(value1, value2) { + verbatim_2i_0o("event_write", value1, value2) + } + + // @dev Write 1-th topic and first data chunk + function writeFirstTopicWithDataChunk() { + let topic1 := getExtraAbiData_1() + let dataChunk := calldataload(0) + eventWrite(topic1, dataChunk) + } + + // @dev Write 1-th and 2-th event topics + function writeFirstTwoTopics() { + let topic1 := getExtraAbiData_1() + let topic2 := getExtraAbiData_2() + eventWrite(topic1, topic2) + } + + // @dev Write 3-th topic and first data chunk + function writeThirdTopicWithDataChunk() { + let topic3 := getExtraAbiData_3() + let dataChunk := calldataload(0) + eventWrite(topic3, dataChunk) + } + + // @dev Write 3-th and 4-th event topics + function writeSecondTwoTopics() { + let topic3 := getExtraAbiData_3() + let topic4 := getExtraAbiData_4() + eventWrite(topic3, topic4) + } + + // @dev Reverts the call if a caller hasn't set the "isSystem" flag before calling + // Note: this method is different from the `onlySystemCall` modifier that is used in system contracts. + function onlySystemCall() { + let callFlags := getCallFlags() + let isSystemCall := and(callFlags, 2) + + if iszero(isSystemCall) { + revert(0, 0) + } + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + // Ensure that contract is called on purpose + onlySystemCall() + + let numberOfTopics := getExtraAbiData_0() + // Only 4 indexed fields are allowed, same as on EVM + if gt(numberOfTopics, 4) { + revert(0, 0) + } + + let dataLength := calldatasize() + // Increment number of topics to include the `msg.sender` as a topic + let initializer := add(shl(32, dataLength), add(numberOfTopics, 1)) + eventInitialize(initializer, caller()) + + // Save the pointer to written data + let dataCursor + + // Handle every case separately, to save gas on loops (alternative approach) + switch numberOfTopics + case 0 { + // Nothing to publish + } + case 1 { + writeFirstTopicWithDataChunk() + dataCursor := add(dataCursor, 0x20) + } + case 2 { + writeFirstTwoTopics() + } + case 3 { + writeFirstTwoTopics() + writeThirdTopicWithDataChunk() + dataCursor := add(dataCursor, 0x20) + } + case 4 { + writeFirstTwoTopics() + writeSecondTwoTopics() + } + default { + // Unreachable + revert(0, 0) + } + + // Write all the event data, two words at a time + for {} lt(dataCursor, dataLength) { + dataCursor := add(dataCursor, 0x40) + } { + let chunk1 := calldataload(dataCursor) + let chunk2 := calldataload(add(dataCursor, 0x20)) + eventWrite(chunk1, chunk2) + } + } + } +} diff --git a/system-contracts/contracts/ImmutableSimulator.sol b/system-contracts/contracts/ImmutableSimulator.sol new file mode 100644 index 000000000..a018c92a1 --- /dev/null +++ b/system-contracts/contracts/ImmutableSimulator.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./interfaces/IImmutableSimulator.sol"; +import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice System smart contract that simulates the behavior of immutable variables in Solidity. + * @dev The contract stores the immutable variables created during deployment by other contracts on his storage. + * @dev This simulator is needed so that smart contracts with the same Solidity code but different + * constructor parameters have the same bytecode. + * @dev The users are not expected to call this contract directly, only indirectly via the compiler simulations + * for the immutable variables in Solidity. + */ +contract ImmutableSimulator is IImmutableSimulator { + /// @dev mapping (contract address) => (index of immutable variable) => value + /// @notice that address uses `uint256` type to leave the option to introduce 32-byte address space in future. + mapping(uint256 => mapping(uint256 => bytes32)) internal immutableDataStorage; + + /// @notice Method that returns the immutable with a certain index for a user. + /// @param _dest The address which the immutable belongs to. + /// @param _index The index of the immutable. + /// @return The value of the immutables. + function getImmutable(address _dest, uint256 _index) external view override returns (bytes32) { + return immutableDataStorage[uint256(uint160(_dest))][_index]; + } + + /// @notice Method used by the contract deployer to store the immutables for an account + /// @param _dest The address which to store the immutables for. + /// @param _immutables The list of the immutables. + function setImmutables(address _dest, ImmutableData[] calldata _immutables) external override { + require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract"); + unchecked { + uint256 immutablesLength = _immutables.length; + for (uint256 i = 0; i < immutablesLength; ++i) { + uint256 index = _immutables[i].index; + bytes32 value = _immutables[i].value; + immutableDataStorage[uint256(uint160(_dest))][index] = value; + } + } + } +} diff --git a/system-contracts/contracts/KnownCodesStorage.sol b/system-contracts/contracts/KnownCodesStorage.sol new file mode 100644 index 000000000..2dda7854c --- /dev/null +++ b/system-contracts/contracts/KnownCodesStorage.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {Utils} from "./libraries/Utils.sol"; +import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The storage of this contract will basically serve as a mapping for the known code hashes. + * @dev Code hash is not strictly a hash, it's a structure where the first byte denotes the version of the hash, + * the second byte denotes whether the contract is constructed, and the next two bytes denote the length in 32-byte words. + * words. And then the next 28 bytes is the truncated hash. + */ +contract KnownCodesStorage is IKnownCodesStorage, ISystemContract { + modifier onlyCompressor() { + require(msg.sender == address(COMPRESSOR_CONTRACT), "Callable only by the compressor"); + _; + } + + /// @notice The method that is used by the bootloader to mark several bytecode hashes as known. + /// @param _shouldSendToL1 Whether the bytecode should be sent on L1. + /// @param _hashes Hashes of the bytecodes to be marked as known. + function markFactoryDeps(bool _shouldSendToL1, bytes32[] calldata _hashes) external onlyCallFromBootloader { + unchecked { + uint256 hashesLen = _hashes.length; + for (uint256 i = 0; i < hashesLen; ++i) { + _markBytecodeAsPublished(_hashes[i], _shouldSendToL1); + } + } + } + + /// @notice The method used to mark a single bytecode hash as known. + /// @dev Only trusted contacts can call this method, currently only the bytecode compressor. + /// @param _bytecodeHash The hash of the bytecode that is marked as known. + function markBytecodeAsPublished(bytes32 _bytecodeHash) external onlyCompressor { + _markBytecodeAsPublished(_bytecodeHash, false); + } + + /// @notice The method used to mark a single bytecode hash as known + /// @param _bytecodeHash The hash of the bytecode that is marked as known + /// @param _shouldSendToL1 Whether the bytecode should be sent on L1 + function _markBytecodeAsPublished(bytes32 _bytecodeHash, bool _shouldSendToL1) internal { + if (getMarker(_bytecodeHash) == 0) { + _validateBytecode(_bytecodeHash); + + if (_shouldSendToL1) { + L1_MESSENGER_CONTRACT.requestBytecodeL1Publication(_bytecodeHash); + } + + // Save as known, to not resend the log to L1 + assembly { + sstore(_bytecodeHash, 1) + } + + emit MarkedAsKnown(_bytecodeHash, _shouldSendToL1); + } + } + + /// @notice Returns the marker stored for a bytecode hash. 1 means that the bytecode hash is known + /// and can be used for deploying contracts. 0 otherwise. + function getMarker(bytes32 _hash) public view override returns (uint256 marker) { + assembly { + marker := sload(_hash) + } + } + + /// @notice Validates the format of bytecodehash + /// @dev zk-circuit accepts & handles only valid format of bytecode hash, other input has undefined behavior + /// That's why we need to validate it + function _validateBytecode(bytes32 _bytecodeHash) internal pure { + uint8 version = uint8(_bytecodeHash[0]); + require(version == 1 && _bytecodeHash[1] == bytes1(0), "Incorrectly formatted bytecodeHash"); + + require(Utils.bytecodeLenInWords(_bytecodeHash) % 2 == 1, "Code length in words must be odd"); + } +} diff --git a/system-contracts/contracts/L1Messenger.sol b/system-contracts/contracts/L1Messenger.sol new file mode 100644 index 000000000..47ee32657 --- /dev/null +++ b/system-contracts/contracts/L1Messenger.sol @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {IL1Messenger, L2ToL1Log, L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L2_TO_L1_LOG_SERIALIZE_SIZE, STATE_DIFF_COMPRESSION_VERSION_NUMBER} from "./interfaces/IL1Messenger.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {EfficientCall} from "./libraries/EfficientCall.sol"; +import {Utils} from "./libraries/Utils.sol"; +import {SystemLogKey, SYSTEM_CONTEXT_CONTRACT, KNOWN_CODE_STORAGE_CONTRACT, COMPRESSOR_CONTRACT, STATE_DIFF_ENTRY_SIZE, MAX_ALLOWED_PUBDATA_PER_BATCH, L2_TO_L1_LOGS_MERKLE_TREE_LEAVES} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Smart contract for sending arbitrary length messages to L1 + * @dev by default ZkSync can send fixed length messages on L1. + * A fixed length message has 4 parameters `senderAddress` `isService`, `key`, `value`, + * the first one is taken from the context, the other three are chosen by the sender. + * @dev To send a variable length message we use this trick: + * - This system contract accepts a arbitrary length message and sends a fixed length message with + * parameters `senderAddress == this`, `marker == true`, `key == msg.sender`, `value == keccak256(message)`. + * - The contract on L1 accepts all sent messages and if the message came from this system contract + * it requires that the preimage of `value` be provided. + */ +contract L1Messenger is IL1Messenger, ISystemContract { + /// @notice Sequential hash of logs sent in the current block. + /// @dev Will be reset at the end of the block to zero value. + bytes32 internal chainedLogsHash; + + /// @notice Number of logs sent in the current block. + /// @dev Will be reset at the end of the block to zero value. + uint256 internal numberOfLogsToProcess; + + /// @notice Sequential hash of hashes of the messages sent in the current block. + /// @dev Will be reset at the end of the block to zero value. + bytes32 internal chainedMessagesHash; + + /// @notice Sequential hash of bytecode hashes that needs to published + /// according to the current block execution invariant. + /// @dev Will be reset at the end of the block to zero value. + bytes32 internal chainedL1BytecodesRevealDataHash; + + /// The gas cost of processing one keccak256 round. + uint256 internal constant KECCAK_ROUND_GAS_COST = 40; + + /// The number of bytes processed in one keccak256 round. + uint256 internal constant KECCAK_ROUND_NUMBER_OF_BYTES = 136; + + /// The gas cost of calculation of keccak256 of bytes array of such length. + function keccakGasCost(uint256 _length) internal pure returns (uint256) { + return KECCAK_ROUND_GAS_COST * (_length / KECCAK_ROUND_NUMBER_OF_BYTES + 1); + } + + /// The gas cost of processing one sha256 round. + uint256 internal constant SHA256_ROUND_GAS_COST = 7; + + /// The number of bytes processed in one sha256 round. + uint256 internal constant SHA256_ROUND_NUMBER_OF_BYTES = 64; + + /// The gas cost of calculation of sha256 of bytes array of such length. + function sha256GasCost(uint256 _length) internal pure returns (uint256) { + return SHA256_ROUND_GAS_COST * ((_length + 8) / SHA256_ROUND_NUMBER_OF_BYTES + 1); + } + + /// @notice Sends L2ToL1Log. + /// @dev Can be called only by a system contract. + function sendL2ToL1Log( + bool _isService, + bytes32 _key, + bytes32 _value + ) external onlyCallFromSystemContract returns (uint256 logIdInMerkleTree) { + L2ToL1Log memory l2ToL1Log = L2ToL1Log({ + l2ShardId: 0, + isService: _isService, + txNumberInBlock: SYSTEM_CONTEXT_CONTRACT.txNumberInBlock(), + sender: msg.sender, + key: _key, + value: _value + }); + logIdInMerkleTree = _processL2ToL1Log(l2ToL1Log); + + // We need to charge cost of hashing, as it will be used in `publishPubdataAndClearState`: + // - keccakGasCost(L2_TO_L1_LOG_SERIALIZE_SIZE) and keccakGasCost(64) when reconstructing L2ToL1Log + // - at most 1 time keccakGasCost(64) when building the Merkle tree (as merkle tree can contain + // ~2*N nodes, where the first N nodes are leaves the hash of which is calculated on the previous step). + uint256 gasToPay = keccakGasCost(L2_TO_L1_LOG_SERIALIZE_SIZE) + 2 * keccakGasCost(64); + SystemContractHelper.burnGas(Utils.safeCastToU32(gasToPay)); + } + + /// @notice Internal function to send L2ToL1Log. + function _processL2ToL1Log(L2ToL1Log memory _l2ToL1Log) internal returns (uint256 logIdInMerkleTree) { + bytes32 hashedLog = keccak256( + abi.encodePacked( + _l2ToL1Log.l2ShardId, + _l2ToL1Log.isService, + _l2ToL1Log.txNumberInBlock, + _l2ToL1Log.sender, + _l2ToL1Log.key, + _l2ToL1Log.value + ) + ); + + chainedLogsHash = keccak256(abi.encode(chainedLogsHash, hashedLog)); + + logIdInMerkleTree = numberOfLogsToProcess; + numberOfLogsToProcess++; + + emit L2ToL1LogSent(_l2ToL1Log); + } + + /// @notice Public functionality to send messages to L1. + function sendToL1(bytes calldata _message) external override returns (bytes32 hash) { + uint256 gasBeforeMessageHashing = gasleft(); + hash = EfficientCall.keccak(_message); + uint256 gasSpentOnMessageHashing = gasBeforeMessageHashing - gasleft(); + + /// Store message record + chainedMessagesHash = keccak256(abi.encode(chainedMessagesHash, hash)); + + /// Store log record + L2ToL1Log memory l2ToL1Log = L2ToL1Log({ + l2ShardId: 0, + isService: true, + txNumberInBlock: SYSTEM_CONTEXT_CONTRACT.txNumberInBlock(), + sender: address(this), + key: bytes32(uint256(uint160(msg.sender))), + value: hash + }); + _processL2ToL1Log(l2ToL1Log); + + // Get cost of one byte pubdata in gas from context. + uint256 meta = SystemContractHelper.getZkSyncMetaBytes(); + uint32 gasPerPubdataBytes = SystemContractHelper.getGasPerPubdataByteFromMeta(meta); + + uint256 pubdataLen; + unchecked { + // 4 bytes used to encode the length of the message (see `publishPubdataAndClearState`) + // L2_TO_L1_LOG_SERIALIZE_SIZE bytes used to encode L2ToL1Log + pubdataLen = 4 + _message.length + L2_TO_L1_LOG_SERIALIZE_SIZE; + } + + // We need to charge cost of hashing, as it will be used in `publishPubdataAndClearState`: + // - keccakGasCost(L2_TO_L1_LOG_SERIALIZE_SIZE) and keccakGasCost(64) when reconstructing L2ToL1Log + // - keccakGasCost(64) and gasSpentOnMessageHashing when reconstructing Messages + // - at most 1 time keccakGasCost(64) when building the Merkle tree (as merkle tree can contain + // ~2*N nodes, where the first N nodes are leaves the hash of which is calculated on the previous step). + uint256 gasToPay = pubdataLen * + gasPerPubdataBytes + + keccakGasCost(L2_TO_L1_LOG_SERIALIZE_SIZE) + + 3 * + keccakGasCost(64) + + gasSpentOnMessageHashing; + SystemContractHelper.burnGas(Utils.safeCastToU32(gasToPay)); + + emit L1MessageSent(msg.sender, hash, _message); + } + + /// @dev Can be called only by KnownCodesStorage system contract. + function requestBytecodeL1Publication( + bytes32 _bytecodeHash + ) external override onlyCallFrom(address(KNOWN_CODE_STORAGE_CONTRACT)) { + chainedL1BytecodesRevealDataHash = keccak256(abi.encode(chainedL1BytecodesRevealDataHash, _bytecodeHash)); + + uint256 bytecodeLen = Utils.bytecodeLenInBytes(_bytecodeHash); + + // Get cost of one byte pubdata in gas from context. + uint256 meta = SystemContractHelper.getZkSyncMetaBytes(); + uint32 gasPerPubdataBytes = SystemContractHelper.getGasPerPubdataByteFromMeta(meta); + + uint256 pubdataLen; + unchecked { + // 4 bytes used to encode the length of the bytecode (see `publishPubdataAndClearState`) + pubdataLen = 4 + bytecodeLen; + } + + // We need to charge cost of hashing, as it will be used in `publishPubdataAndClearState` + uint256 gasToPay = pubdataLen * gasPerPubdataBytes + sha256GasCost(bytecodeLen) + keccakGasCost(64); + SystemContractHelper.burnGas(Utils.safeCastToU32(gasToPay)); + + emit BytecodeL1PublicationRequested(_bytecodeHash); + } + + /// @notice Verifies that the {_totalL2ToL1PubdataAndStateDiffs} reflects what occurred within the L1Batch and that + /// the compressed statediffs are equivalent to the full state diffs. + /// @param _totalL2ToL1PubdataAndStateDiffs The total pubdata and uncompressed state diffs of transactions that were + /// processed in the current L1 Batch. Pubdata consists of L2 to L1 Logs, messages, deployed bytecode, and state diffs. + /// @dev Function that should be called exactly once per L1 Batch by the bootloader. + /// @dev Checks that totalL2ToL1Pubdata is strictly packed data that should to be published to L1. + /// @dev The data passed in also contains the encoded state diffs to be checked again, however this is aux data that is not + /// part of the committed pubdata. + /// @dev Performs calculation of L2ToL1Logs merkle tree root, "sends" such root and keccak256(totalL2ToL1Pubdata) + /// to L1 using low-level (VM) L2Log. + function publishPubdataAndClearState( + bytes calldata _totalL2ToL1PubdataAndStateDiffs + ) external onlyCallFromBootloader { + uint256 calldataPtr = 0; + + /// Check logs + uint32 numberOfL2ToL1Logs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); + require(numberOfL2ToL1Logs <= L2_TO_L1_LOGS_MERKLE_TREE_LEAVES, "Too many L2->L1 logs"); + calldataPtr += 4; + + bytes32[] memory l2ToL1LogsTreeArray = new bytes32[](L2_TO_L1_LOGS_MERKLE_TREE_LEAVES); + bytes32 reconstructedChainedLogsHash; + for (uint256 i = 0; i < numberOfL2ToL1Logs; ++i) { + bytes32 hashedLog = EfficientCall.keccak( + _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + L2_TO_L1_LOG_SERIALIZE_SIZE] + ); + calldataPtr += L2_TO_L1_LOG_SERIALIZE_SIZE; + l2ToL1LogsTreeArray[i] = hashedLog; + reconstructedChainedLogsHash = keccak256(abi.encode(reconstructedChainedLogsHash, hashedLog)); + } + require( + reconstructedChainedLogsHash == chainedLogsHash, + "reconstructedChainedLogsHash is not equal to chainedLogsHash" + ); + for (uint256 i = numberOfL2ToL1Logs; i < L2_TO_L1_LOGS_MERKLE_TREE_LEAVES; ++i) { + l2ToL1LogsTreeArray[i] = L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH; + } + uint256 nodesOnCurrentLevel = L2_TO_L1_LOGS_MERKLE_TREE_LEAVES; + while (nodesOnCurrentLevel > 1) { + nodesOnCurrentLevel /= 2; + for (uint256 i = 0; i < nodesOnCurrentLevel; ++i) { + l2ToL1LogsTreeArray[i] = keccak256( + abi.encode(l2ToL1LogsTreeArray[2 * i], l2ToL1LogsTreeArray[2 * i + 1]) + ); + } + } + bytes32 l2ToL1LogsTreeRoot = l2ToL1LogsTreeArray[0]; + + /// Check messages + uint32 numberOfMessages = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); + calldataPtr += 4; + bytes32 reconstructedChainedMessagesHash; + for (uint256 i = 0; i < numberOfMessages; ++i) { + uint32 currentMessageLength = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); + calldataPtr += 4; + bytes32 hashedMessage = EfficientCall.keccak( + _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + currentMessageLength] + ); + calldataPtr += currentMessageLength; + reconstructedChainedMessagesHash = keccak256(abi.encode(reconstructedChainedMessagesHash, hashedMessage)); + } + require( + reconstructedChainedMessagesHash == chainedMessagesHash, + "reconstructedChainedMessagesHash is not equal to chainedMessagesHash" + ); + + /// Check bytecodes + uint32 numberOfBytecodes = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); + calldataPtr += 4; + bytes32 reconstructedChainedL1BytecodesRevealDataHash; + for (uint256 i = 0; i < numberOfBytecodes; ++i) { + uint32 currentBytecodeLength = uint32( + bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]) + ); + calldataPtr += 4; + reconstructedChainedL1BytecodesRevealDataHash = keccak256( + abi.encode( + reconstructedChainedL1BytecodesRevealDataHash, + Utils.hashL2Bytecode( + _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + currentBytecodeLength] + ) + ) + ); + calldataPtr += currentBytecodeLength; + } + require( + reconstructedChainedL1BytecodesRevealDataHash == chainedL1BytecodesRevealDataHash, + "reconstructedChainedL1BytecodesRevealDataHash is not equal to chainedL1BytecodesRevealDataHash" + ); + + /// Check State Diffs + /// encoding is as follows: + /// header (1 byte version, 3 bytes total len of compressed, 1 byte enumeration index size, 2 bytes number of initial writes) + /// body (N bytes of initial writes [32 byte derived key || compressed value], M bytes repeated writes [enumeration index || compressed value]) + /// encoded state diffs: [20bytes address][32bytes key][32bytes derived key][8bytes enum index][32bytes initial value][32bytes final value] + require( + uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]))) == + STATE_DIFF_COMPRESSION_VERSION_NUMBER, + "state diff compression version mismatch" + ); + calldataPtr++; + + uint24 compressedStateDiffSize = uint24(bytes3(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 3])); + calldataPtr += 3; + + uint8 enumerationIndexSize = uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr])); + calldataPtr++; + + bytes calldata compressedStateDiffs = _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + + compressedStateDiffSize]; + calldataPtr += compressedStateDiffSize; + + bytes calldata totalL2ToL1Pubdata = _totalL2ToL1PubdataAndStateDiffs[:calldataPtr]; + + require(calldataPtr <= MAX_ALLOWED_PUBDATA_PER_BATCH, "L1 Messenger pubdata is too long"); + + uint32 numberOfStateDiffs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); + calldataPtr += 4; + + bytes calldata stateDiffs = _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + + (numberOfStateDiffs * STATE_DIFF_ENTRY_SIZE)]; + calldataPtr += numberOfStateDiffs * STATE_DIFF_ENTRY_SIZE; + + bytes32 stateDiffHash = COMPRESSOR_CONTRACT.verifyCompressedStateDiffs( + numberOfStateDiffs, + enumerationIndexSize, + stateDiffs, + compressedStateDiffs + ); + + /// Check for calldata strict format + require(calldataPtr == _totalL2ToL1PubdataAndStateDiffs.length, "Extra data in the totalL2ToL1Pubdata array"); + + /// Native (VM) L2 to L1 log + SystemContractHelper.toL1(true, bytes32(uint256(SystemLogKey.L2_TO_L1_LOGS_TREE_ROOT_KEY)), l2ToL1LogsTreeRoot); + SystemContractHelper.toL1( + true, + bytes32(uint256(SystemLogKey.TOTAL_L2_TO_L1_PUBDATA_KEY)), + EfficientCall.keccak(totalL2ToL1Pubdata) + ); + SystemContractHelper.toL1(true, bytes32(uint256(SystemLogKey.STATE_DIFF_HASH_KEY)), stateDiffHash); + + /// Clear logs state + chainedLogsHash = bytes32(0); + numberOfLogsToProcess = 0; + chainedMessagesHash = bytes32(0); + chainedL1BytecodesRevealDataHash = bytes32(0); + } +} diff --git a/system-contracts/contracts/L2EthToken.sol b/system-contracts/contracts/L2EthToken.sol new file mode 100644 index 000000000..fbd63ae21 --- /dev/null +++ b/system-contracts/contracts/L2EthToken.sol @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {IEthToken} from "./interfaces/IEthToken.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {MSG_VALUE_SYSTEM_CONTRACT, DEPLOYER_SYSTEM_CONTRACT, BOOTLOADER_FORMAL_ADDRESS, L1_MESSENGER_CONTRACT} from "./Constants.sol"; +import {IMailbox} from "./interfaces/IMailbox.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Native ETH contract. + * @dev It does NOT provide interfaces for personal interaction with tokens like `transfer`, `approve`, and `transferFrom`. + * Instead, this contract is used by the bootloader and `MsgValueSimulator`/`ContractDeployer` system contracts + * to perform the balance changes while simulating the `msg.value` Ethereum behavior. + */ +contract L2EthToken is IEthToken, ISystemContract { + /// @notice The balances of the users. + mapping(address => uint256) internal balance; + + /// @notice The total amount of tokens that have been minted. + uint256 public override totalSupply; + + /// @notice Transfer tokens from one address to another. + /// @param _from The address to transfer the ETH from. + /// @param _to The address to transfer the ETH to. + /// @param _amount The amount of ETH in wei being transferred. + /// @dev This function can be called only by trusted system contracts. + /// @dev This function also emits "Transfer" event, which might be removed + /// later on. + function transferFromTo(address _from, address _to, uint256 _amount) external override { + require( + msg.sender == MSG_VALUE_SYSTEM_CONTRACT || + msg.sender == address(DEPLOYER_SYSTEM_CONTRACT) || + msg.sender == BOOTLOADER_FORMAL_ADDRESS, + "Only system contracts with special access can call this method" + ); + + uint256 fromBalance = balance[_from]; + require(fromBalance >= _amount, "Transfer amount exceeds balance"); + unchecked { + balance[_from] = fromBalance - _amount; + // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by + // decrementing then incrementing. + balance[_to] += _amount; + } + + emit Transfer(_from, _to, _amount); + } + + /// @notice Returns ETH balance of an account + /// @dev It takes `uint256` as an argument to be able to properly simulate the behaviour of the + /// Ethereum's `BALANCE` opcode that accepts uint256 as an argument and truncates any upper bits + /// @param _account The address of the account to return the balance of. + function balanceOf(uint256 _account) external view override returns (uint256) { + return balance[address(uint160(_account))]; + } + + /// @notice Increase the total supply of tokens and balance of the receiver. + /// @dev This method is only callable by the bootloader. + /// @param _account The address which to mint the funds to. + /// @param _amount The amount of ETH in wei to be minted. + function mint(address _account, uint256 _amount) external override onlyCallFromBootloader { + totalSupply += _amount; + balance[_account] += _amount; + emit Mint(_account, _amount); + } + + /// @notice Initiate the ETH withdrawal, funds will be available to claim on L1 `finalizeEthWithdrawal` method. + /// @param _l1Receiver The address on L1 to receive the funds. + function withdraw(address _l1Receiver) external payable override { + uint256 amount = _burnMsgValue(); + + // Send the L2 log, a user could use it as proof of the withdrawal + bytes memory message = _getL1WithdrawMessage(_l1Receiver, amount); + L1_MESSENGER_CONTRACT.sendToL1(message); + + emit Withdrawal(msg.sender, _l1Receiver, amount); + } + + /// @notice Initiate the ETH withdrawal, with the sent message. The funds will be available to claim on L1 `finalizeEthWithdrawal` method. + /// @param _l1Receiver The address on L1 to receive the funds. + /// @param _additionalData Additional data to be sent to L1 with the withdrawal. + function withdrawWithMessage(address _l1Receiver, bytes memory _additionalData) external payable override { + uint256 amount = _burnMsgValue(); + + // Send the L2 log, a user could use it as proof of the withdrawal + bytes memory message = _getExtendedWithdrawMessage(_l1Receiver, amount, msg.sender, _additionalData); + L1_MESSENGER_CONTRACT.sendToL1(message); + + emit WithdrawalWithMessage(msg.sender, _l1Receiver, amount, _additionalData); + } + + /// @dev The function burn the sent `msg.value`. + /// NOTE: Since this contract holds the mapping of all ether balances of the system, + /// the sent `msg.value` is added to the `this` balance before the call. + /// So the balance of `address(this)` is always bigger or equal to the `msg.value`! + function _burnMsgValue() internal returns (uint256 amount) { + amount = msg.value; + + // Silent burning of the ether + unchecked { + // This is safe, since this contract holds the ether balances, and if user + // send a `msg.value` it will be added to the contract (`this`) balance. + balance[address(this)] -= amount; + totalSupply -= amount; + } + } + + /// @dev Get the message to be sent to L1 to initiate a withdrawal. + function _getL1WithdrawMessage(address _to, uint256 _amount) internal pure returns (bytes memory) { + return abi.encodePacked(IMailbox.finalizeEthWithdrawal.selector, _to, _amount); + } + + /// @dev Get the message to be sent to L1 to initiate a withdrawal. + function _getExtendedWithdrawMessage( + address _to, + uint256 _amount, + address _sender, + bytes memory _additionalData + ) internal pure returns (bytes memory) { + return abi.encodePacked(IMailbox.finalizeEthWithdrawal.selector, _to, _amount, _sender, _additionalData); + } + + /// @dev This method has not been stabilized and might be + /// removed later on. + function name() external pure override returns (string memory) { + return "Ether"; + } + + /// @dev This method has not been stabilized and might be + /// removed later on. + function symbol() external pure override returns (string memory) { + return "ETH"; + } + + /// @dev This method has not been stabilized and might be + /// removed later on. + function decimals() external pure override returns (uint8) { + return 18; + } +} diff --git a/system-contracts/contracts/MsgValueSimulator.sol b/system-contracts/contracts/MsgValueSimulator.sol new file mode 100644 index 000000000..07ed23d4b --- /dev/null +++ b/system-contracts/contracts/MsgValueSimulator.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./libraries/Utils.sol"; +import "./libraries/EfficientCall.sol"; +import "./interfaces/ISystemContract.sol"; +import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, ETH_TOKEN_SYSTEM_CONTRACT} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The contract responsible for simulating transactions with `msg.value` inside zkEVM. + * @dev It accepts value and whether the call should be system in the first extraAbi param and + * the address to call in the second extraAbi param, transfers the funds and uses `mimicCall` to continue the + * call with the same msg.sender. + */ +contract MsgValueSimulator is ISystemContract { + /// @notice Extract value, isSystemCall and to from the extraAbi params. + /// @dev The contract accepts value, the callee and whether the call should a system one via its ABI params. + /// @dev The first ABI param contains the value in the [0..127] bits. The 128th contains + /// the flag whether or not the call should be a system one. + /// The second ABI params contains the callee. + function _getAbiParams() internal view returns (uint256 value, bool isSystemCall, address to) { + value = SystemContractHelper.getExtraAbiData(0); + uint256 addressAsUint = SystemContractHelper.getExtraAbiData(1); + uint256 mask = SystemContractHelper.getExtraAbiData(2); + + isSystemCall = (mask & MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT) != 0; + + to = address(uint160(addressAsUint)); + } + + fallback(bytes calldata _data) external onlySystemCall returns (bytes memory) { + (uint256 value, bool isSystemCall, address to) = _getAbiParams(); + + // Prevent mimic call to the MsgValueSimulator to prevent an unexpected change of callee. + require(to != address(this), "MsgValueSimulator calls itself"); + + if (value != 0) { + (bool success, ) = address(ETH_TOKEN_SYSTEM_CONTRACT).call( + abi.encodeCall(ETH_TOKEN_SYSTEM_CONTRACT.transferFromTo, (msg.sender, to, value)) + ); + + // If the transfer of ETH fails, we do the most Ethereum-like behaviour in such situation: revert(0,0) + if (!success) { + assembly { + revert(0, 0) + } + } + } + + // For the next call this `msg.value` will be used. + SystemContractHelper.setValueForNextFarCall(Utils.safeCastToU128(value)); + + return EfficientCall.mimicCall(gasleft(), to, _data, msg.sender, false, isSystemCall); + } +} diff --git a/system-contracts/contracts/NonceHolder.sol b/system-contracts/contracts/NonceHolder.sol new file mode 100644 index 000000000..b2775f1cb --- /dev/null +++ b/system-contracts/contracts/NonceHolder.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./interfaces/INonceHolder.sol"; +import "./interfaces/IContractDeployer.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice A contract used for managing nonces for accounts. Together with bootloader, + * this contract ensures that the pair (sender, nonce) is always unique, ensuring + * unique transaction hashes. + * @dev The account allows for both ascending growth in nonces and mapping nonces to specific + * stored values in them. + * The users can either marked a range of nonces by increasing the `minNonce`. This way all the nonces + * less than `minNonce` will become used. The other way to mark a certain 256-bit key as nonce is to set + * some value under it in this contract. + * @dev Apart from transaction nonces, this contract also stores the deployment nonce for accounts, that + * will be used for address derivation using CREATE. For the economy of space, this nonce is stored tightly + * packed with the `minNonce`. + * @dev The behavior of some of the methods depends on the nonce ordering of the account. Nonce ordering is a mere suggestion and all the checks that are present + * here serve more as a help to users to prevent from doing mistakes, rather than any invariants. + */ +contract NonceHolder is INonceHolder, ISystemContract { + uint256 constant DEPLOY_NONCE_MULTIPLIER = 2 ** 128; + /// The minNonce can be increased by at 2^32 at a time to prevent it from + /// overflowing beyond 2**128. + uint256 constant MAXIMAL_MIN_NONCE_INCREMENT = 2 ** 32; + + /// RawNonces for accounts are stored in format + /// minNonce + 2^128 * deploymentNonce, where deploymentNonce + /// is the nonce used for deploying smart contracts. + mapping(uint256 => uint256) internal rawNonces; + + /// Mapping of values under nonces for accounts. + /// The main key of the mapping is the 256-bit address of the account, while the + /// inner mapping is a mapping from a nonce to the value stored there. + mapping(uint256 => mapping(uint256 => uint256)) internal nonceValues; + + /// @notice Returns the current minimal nonce for account. + /// @param _address The account to return the minimal nonce for + /// @return The current minimal nonce for this account. + function getMinNonce(address _address) public view returns (uint256) { + uint256 addressAsKey = uint256(uint160(_address)); + (, uint256 minNonce) = _splitRawNonce(rawNonces[addressAsKey]); + + return minNonce; + } + + /// @notice Returns the raw version of the current minimal nonce + /// @dev It is equal to minNonce + 2^128 * deployment nonce. + /// @param _address The account to return the raw nonce for + /// @return The raw nonce for this account. + function getRawNonce(address _address) public view returns (uint256) { + uint256 addressAsKey = uint256(uint160(_address)); + return rawNonces[addressAsKey]; + } + + /// @notice Increases the minimal nonce for the msg.sender and returns the previous one. + /// @param _value The number by which to increase the minimal nonce for msg.sender. + /// @return oldMinNonce The value of the minimal nonce for msg.sender before the increase. + function increaseMinNonce(uint256 _value) public onlySystemCall returns (uint256 oldMinNonce) { + require(_value <= MAXIMAL_MIN_NONCE_INCREMENT, "The value for incrementing the nonce is too high"); + + uint256 addressAsKey = uint256(uint160(msg.sender)); + uint256 oldRawNonce = rawNonces[addressAsKey]; + + unchecked { + rawNonces[addressAsKey] = (oldRawNonce + _value); + } + + (, oldMinNonce) = _splitRawNonce(oldRawNonce); + } + + /// @notice Sets the nonce value `key` for the msg.sender as used. + /// @param _key The nonce key under which the value will be set. + /// @param _value The value to store under the _key. + /// @dev The value must be non-zero. + function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall { + IContractDeployer.AccountInfo memory accountInfo = DEPLOYER_SYSTEM_CONTRACT.getAccountInfo(msg.sender); + + require(_value != 0, "Nonce value cannot be set to 0"); + // If an account has sequential nonce ordering, we enforce that the previous + // nonce has already been used. + if (accountInfo.nonceOrdering == IContractDeployer.AccountNonceOrdering.Sequential && _key != 0) { + require(isNonceUsed(msg.sender, _key - 1), "Previous nonce has not been used"); + } + + uint256 addressAsKey = uint256(uint160(msg.sender)); + + nonceValues[addressAsKey][_key] = _value; + + emit ValueSetUnderNonce(msg.sender, _key, _value); + } + + /// @notice Gets the value stored under a custom nonce for msg.sender. + /// @param _key The key under which to get the stored value. + /// @return The value stored under the `_key` for the msg.sender. + function getValueUnderNonce(uint256 _key) public view returns (uint256) { + uint256 addressAsKey = uint256(uint160(msg.sender)); + return nonceValues[addressAsKey][_key]; + } + + /// @notice A convenience method to increment the minimal nonce if it is equal + /// to the `_expectedNonce`. + /// @param _expectedNonce The expected minimal nonce for the account. + function incrementMinNonceIfEquals(uint256 _expectedNonce) external onlySystemCall { + uint256 addressAsKey = uint256(uint160(msg.sender)); + uint256 oldRawNonce = rawNonces[addressAsKey]; + + (, uint256 oldMinNonce) = _splitRawNonce(oldRawNonce); + require(oldMinNonce == _expectedNonce, "Incorrect nonce"); + + unchecked { + rawNonces[addressAsKey] = oldRawNonce + 1; + } + } + + /// @notice Returns the deployment nonce for the accounts used for CREATE opcode. + /// @param _address The address to return the deploy nonce of. + /// @return deploymentNonce The deployment nonce of the account. + function getDeploymentNonce(address _address) external view returns (uint256 deploymentNonce) { + uint256 addressAsKey = uint256(uint160(_address)); + (deploymentNonce, ) = _splitRawNonce(rawNonces[addressAsKey]); + + return deploymentNonce; + } + + /// @notice Increments the deployment nonce for the account and returns the previous one. + /// @param _address The address of the account which to return the deploy nonce for. + /// @return prevDeploymentNonce The deployment nonce at the time this function is called. + function incrementDeploymentNonce(address _address) external returns (uint256 prevDeploymentNonce) { + require( + msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), + "Only the contract deployer can increment the deployment nonce" + ); + uint256 addressAsKey = uint256(uint160(_address)); + uint256 oldRawNonce = rawNonces[addressAsKey]; + + unchecked { + rawNonces[addressAsKey] = (oldRawNonce + DEPLOY_NONCE_MULTIPLIER); + } + + (prevDeploymentNonce, ) = _splitRawNonce(oldRawNonce); + } + + function isNonceUsed(address _address, uint256 _nonce) public view returns (bool) { + uint256 addressAsKey = uint256(uint160(_address)); + return (_nonce < getMinNonce(_address) || nonceValues[addressAsKey][_nonce] > 0); + } + + /// @notice Checks and reverts based on whether the nonce is used (not used). + /// @param _address The address the nonce of which is being checked. + /// @param _key The nonce value which is tested. + /// @param _shouldBeUsed The flag for the method. If `true`, the method checks that whether this nonce + /// is marked as used and reverts if this is not the case. If `false`, this method will check that the nonce + /// has *not* been used yet, and revert otherwise. + /// @dev This method should be used by the bootloader. + function validateNonceUsage(address _address, uint256 _key, bool _shouldBeUsed) external view { + bool isUsed = isNonceUsed(_address, _key); + + if (isUsed && !_shouldBeUsed) { + revert("Reusing the same nonce twice"); + } else if (!isUsed && _shouldBeUsed) { + revert("The nonce was not set as used"); + } + } + + /// @notice Splits the raw nonce value into the deployment nonce and the minimal nonce. + /// @param _rawMinNonce The value of the raw minimal nonce (equal to minNonce + deploymentNonce* 2**128). + /// @return deploymentNonce and minNonce. + function _splitRawNonce(uint256 _rawMinNonce) internal pure returns (uint256 deploymentNonce, uint256 minNonce) { + deploymentNonce = _rawMinNonce / DEPLOY_NONCE_MULTIPLIER; + minNonce = _rawMinNonce % DEPLOY_NONCE_MULTIPLIER; + } +} diff --git a/system-contracts/contracts/SystemContext.sol b/system-contracts/contracts/SystemContext.sol new file mode 100644 index 000000000..67f9248e9 --- /dev/null +++ b/system-contracts/contracts/SystemContext.sol @@ -0,0 +1,483 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {ISystemContext} from "./interfaces/ISystemContext.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {ISystemContextDeprecated} from "./interfaces/ISystemContextDeprecated.sol"; +import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {BOOTLOADER_FORMAL_ADDRESS, SystemLogKey} from "./Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Contract that stores some of the context variables, that may be either + * block-scoped, tx-scoped or system-wide. + */ +contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContract { + /// @notice The number of latest L2 blocks to store. + /// @dev EVM requires us to be able to query the hashes of previous 256 blocks. + /// We could either: + /// - Store the latest 256 hashes (and strictly rely that we do not accidentally override the hash of the block 256 blocks ago) + /// - Store the latest 257 blocks's hashes. + uint256 internal constant MINIBLOCK_HASHES_TO_STORE = 257; + + /// @notice The chainId of the network. It is set at the genesis. + uint256 public chainId; + + /// @notice The `tx.origin` in the current transaction. + /// @dev It is updated before each transaction by the bootloader + address public origin; + + /// @notice The `tx.gasPrice` in the current transaction. + /// @dev It is updated before each transaction by the bootloader + uint256 public gasPrice; + + /// @notice The current block's gasLimit. + uint256 public blockGasLimit = type(uint32).max; + + /// @notice The `block.coinbase` in the current transaction. + /// @dev For the support of coinbase, we will use the bootloader formal address for now + address public coinbase = BOOTLOADER_FORMAL_ADDRESS; + + /// @notice Formal `block.difficulty` parameter. + uint256 public difficulty = 2500000000000000; + + /// @notice The `block.basefee`. + /// @dev It is currently a constant. + uint256 public baseFee; + + /// @notice The number and the timestamp of the current L1 batch stored packed. + BlockInfo internal currentBatchInfo; + + /// @notice The hashes of batches. + /// @dev It stores batch hashes for all previous batches. + mapping(uint256 => bytes32) internal batchHash; + + /// @notice The number and the timestamp of the current L2 block. + BlockInfo internal currentL2BlockInfo; + + /// @notice The rolling hash of the transactions in the current L2 block. + bytes32 internal currentL2BlockTxsRollingHash; + + /// @notice The hashes of L2 blocks. + /// @dev It stores block hashes for previous L2 blocks. Note, in order to make publishing the hashes + /// of the miniblocks cheaper, we only store the previous MINIBLOCK_HASHES_TO_STORE ones. Since whenever we need to publish a state + /// diff, a pair of is published and for cached keys only 8-byte id is used instead of 32 bytes. + /// By having this data in a cyclic array of MINIBLOCK_HASHES_TO_STORE blocks, we bring the costs down by 40% (i.e. 40 bytes per miniblock instead of 64 bytes). + /// @dev The hash of a miniblock with number N would be stored under slot N%MINIBLOCK_HASHES_TO_STORE. + /// @dev Hashes of the blocks older than the ones which are stored here can be calculated as _calculateLegacyL2BlockHash(blockNumber). + bytes32[MINIBLOCK_HASHES_TO_STORE] internal l2BlockHash; + + /// @notice To make migration to L2 blocks smoother, we introduce a temporary concept of virtual L2 blocks, the data + /// about which will be returned by the EVM-like methods: block.number/block.timestamp/blockhash. + /// - Their number will start from being equal to the number of the batch and it will increase until it reaches the L2 block number. + /// - Their timestamp is updated each time a new virtual block is created. + /// - Their hash is calculated as `keccak256(uint256(number))` + BlockInfo internal currentVirtualL2BlockInfo; + + /// @notice The information about the virtual blocks upgrade, which tracks when the migration to the L2 blocks has started and finished. + VirtualBlockUpgradeInfo internal virtualBlockUpgradeInfo; + + /// @notice Number of current transaction in block. + uint16 public txNumberInBlock; + + /// @notice Set the current tx origin. + /// @param _newOrigin The new tx origin. + function setTxOrigin(address _newOrigin) external onlyCallFromBootloader { + origin = _newOrigin; + } + + /// @notice Set the the current gas price. + /// @param _gasPrice The new tx gasPrice. + function setGasPrice(uint256 _gasPrice) external onlyCallFromBootloader { + gasPrice = _gasPrice; + } + + /// @notice The method that emulates `blockhash` opcode in EVM. + /// @dev Just like the blockhash in the EVM, it returns bytes32(0), + /// when queried about hashes that are older than 256 blocks ago. + /// @dev Since zksolc compiler calls this method to emulate `blockhash`, + /// its signature can not be changed to `getL2BlockHashEVM`. + /// @return hash The blockhash of the block with the given number. + function getBlockHashEVM(uint256 _block) external view returns (bytes32 hash) { + uint128 blockNumber = currentVirtualL2BlockInfo.number; + + VirtualBlockUpgradeInfo memory currentVirtualBlockUpgradeInfo = virtualBlockUpgradeInfo; + + // Due to virtual blocks upgrade, we'll have to use the following logic for retreiving the blockhash: + // 1. If the block number is out of the 256-block supported range, return 0. + // 2. If the block was created before the upgrade for the virtual blocks (i.e. there we used to use hashes of the batches), + // we return the hash of the batch. + // 3. If the block was created after the day when the virtual blocks have caught up with the L2 blocks, i.e. + // all the information which is returned for users should be for L2 blocks, we return the hash of the corresponding L2 block. + // 4. If the block queried is a virtual blocks, calculate it on the fly. + if (blockNumber <= _block || blockNumber - _block > 256) { + hash = bytes32(0); + } else if (_block < currentVirtualBlockUpgradeInfo.virtualBlockStartBatch) { + // Note, that we will get into this branch only for a brief moment of time, right after the upgrade + // for virtual blocks before 256 virtual blocks are produced. + hash = batchHash[_block]; + } else if ( + _block >= currentVirtualBlockUpgradeInfo.virtualBlockFinishL2Block && + currentVirtualBlockUpgradeInfo.virtualBlockFinishL2Block > 0 + ) { + hash = _getLatest257L2blockHash(_block); + } else { + // Important: we do not want this number to ever collide with the L2 block hash (either new or old one) and so + // that's why the legacy L2 blocks' hashes are keccak256(abi.encodePacked(uint32(_block))), while these are equivalent to + // keccak256(abi.encodePacked(_block)) + hash = keccak256(abi.encode(_block)); + } + } + + /// @notice Returns the hash of the given batch. + /// @param _batchNumber The number of the batch. + /// @return hash The hash of the batch. + function getBatchHash(uint256 _batchNumber) external view returns (bytes32 hash) { + hash = batchHash[_batchNumber]; + } + + /// @notice Returns the current batch's number and timestamp. + /// @return batchNumber and batchTimestamp tuple of the current batch's number and the current batch's timestamp + function getBatchNumberAndTimestamp() public view returns (uint128 batchNumber, uint128 batchTimestamp) { + BlockInfo memory batchInfo = currentBatchInfo; + batchNumber = batchInfo.number; + batchTimestamp = batchInfo.timestamp; + } + + /// @notice Returns the current block's number and timestamp. + /// @return blockNumber and blockTimestamp tuple of the current L2 block's number and the current block's timestamp + function getL2BlockNumberAndTimestamp() public view returns (uint128 blockNumber, uint128 blockTimestamp) { + BlockInfo memory blockInfo = currentL2BlockInfo; + blockNumber = blockInfo.number; + blockTimestamp = blockInfo.timestamp; + } + + /// @notice Returns the current L2 block's number. + /// @dev Since zksolc compiler calls this method to emulate `block.number`, + /// its signature can not be changed to `getL2BlockNumber`. + /// @return blockNumber The current L2 block's number. + function getBlockNumber() public view returns (uint128) { + return currentVirtualL2BlockInfo.number; + } + + /// @notice Returns the current L2 block's timestamp. + /// @dev Since zksolc compiler calls this method to emulate `block.timestamp`, + /// its signature can not be changed to `getL2BlockTimestamp`. + /// @return timestamp The current L2 block's timestamp. + function getBlockTimestamp() public view returns (uint128) { + return currentVirtualL2BlockInfo.timestamp; + } + + /// @notice Assuming that block is one of the last MINIBLOCK_HASHES_TO_STORE ones, returns its hash. + /// @param _block The number of the block. + /// @return hash The hash of the block. + function _getLatest257L2blockHash(uint256 _block) internal view returns (bytes32) { + return l2BlockHash[_block % MINIBLOCK_HASHES_TO_STORE]; + } + + /// @notice Assuming that the block is one of the last MINIBLOCK_HASHES_TO_STORE ones, sets its hash. + /// @param _block The number of the block. + /// @param _hash The hash of the block. + function _setL2BlockHash(uint256 _block, bytes32 _hash) internal { + l2BlockHash[_block % MINIBLOCK_HASHES_TO_STORE] = _hash; + } + + /// @notice Calculates the hash of an L2 block. + /// @param _blockNumber The number of the L2 block. + /// @param _blockTimestamp The timestamp of the L2 block. + /// @param _prevL2BlockHash The hash of the previous L2 block. + /// @param _blockTxsRollingHash The rolling hash of the transactions in the L2 block. + function _calculateL2BlockHash( + uint128 _blockNumber, + uint128 _blockTimestamp, + bytes32 _prevL2BlockHash, + bytes32 _blockTxsRollingHash + ) internal pure returns (bytes32) { + return keccak256(abi.encode(_blockNumber, _blockTimestamp, _prevL2BlockHash, _blockTxsRollingHash)); + } + + /// @notice Calculates the legacy block hash of L2 block, which were used before the upgrade where + /// the advanced block hashes were introduced. + /// @param _blockNumber The number of the L2 block. + function _calculateLegacyL2BlockHash(uint128 _blockNumber) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(uint32(_blockNumber))); + } + + /// @notice Performs the upgrade where we transition to the L2 blocks. + /// @param _l2BlockNumber The number of the new L2 block. + /// @param _expectedPrevL2BlockHash The expected hash of the previous L2 block. + /// @param _isFirstInBatch Whether this method is called for the first time in the batch. + function _upgradeL2Blocks(uint128 _l2BlockNumber, bytes32 _expectedPrevL2BlockHash, bool _isFirstInBatch) internal { + require(_isFirstInBatch, "Upgrade transaction must be first"); + + // This is how it will be commonly done in practice, but it will simplify some logic later + require(_l2BlockNumber > 0, "L2 block number is never expected to be zero"); + + unchecked { + bytes32 correctPrevBlockHash = _calculateLegacyL2BlockHash(_l2BlockNumber - 1); + require(correctPrevBlockHash == _expectedPrevL2BlockHash, "The previous L2 block hash is incorrect"); + + // Whenever we'll be queried about the hashes of the blocks before the upgrade, + // we'll use batches' hashes, so we don't need to store 256 previous hashes. + // However, we do need to store the last previous hash in order to be able to correctly calculate the + // hash of the new L2 block. + _setL2BlockHash(_l2BlockNumber - 1, correctPrevBlockHash); + } + } + + /// @notice Creates new virtual blocks, while ensuring they don't exceed the L2 block number. + /// @param _l2BlockNumber The number of the new L2 block. + /// @param _maxVirtualBlocksToCreate The maximum number of virtual blocks to create with this L2 block. + /// @param _newTimestamp The timestamp of the new L2 block, which is also the timestamp of the new virtual block. + function _setVirtualBlock( + uint128 _l2BlockNumber, + uint128 _maxVirtualBlocksToCreate, + uint128 _newTimestamp + ) internal { + if (virtualBlockUpgradeInfo.virtualBlockFinishL2Block != 0) { + // No need to to do anything about virtual blocks anymore + // All the info is the same as for L2 blocks. + currentVirtualL2BlockInfo = currentL2BlockInfo; + return; + } + + BlockInfo memory virtualBlockInfo = currentVirtualL2BlockInfo; + + if (currentVirtualL2BlockInfo.number == 0 && virtualBlockInfo.timestamp == 0) { + uint128 currentBatchNumber = currentBatchInfo.number; + + // The virtual block is set for the first time. We can count it as 1 creation of a virtual block. + // Note, that when setting the virtual block number we use the batch number to make a smoother upgrade from batch number to + // the L2 block number. + virtualBlockInfo.number = currentBatchNumber; + // Remembering the batch number on which the upgrade to the virtual blocks has been done. + virtualBlockUpgradeInfo.virtualBlockStartBatch = currentBatchNumber; + + require(_maxVirtualBlocksToCreate > 0, "Can't initialize the first virtual block"); + _maxVirtualBlocksToCreate -= 1; + } else if (_maxVirtualBlocksToCreate == 0) { + // The virtual blocks have been already initialized, but the operator didn't ask to create + // any new virtual blocks. So we can just return. + return; + } + + virtualBlockInfo.number += _maxVirtualBlocksToCreate; + virtualBlockInfo.timestamp = _newTimestamp; + + // The virtual block number must never exceed the L2 block number. + // We do not use a `require` here, since the virtual blocks are a temporary solution to let the Solidity's `block.number` + // catch up with the L2 block number and so the situation where virtualBlockInfo.number starts getting larger + // than _l2BlockNumber is expected once virtual blocks have caught up the L2 blocks. + if (virtualBlockInfo.number >= _l2BlockNumber) { + virtualBlockUpgradeInfo.virtualBlockFinishL2Block = _l2BlockNumber; + virtualBlockInfo.number = _l2BlockNumber; + } + + currentVirtualL2BlockInfo = virtualBlockInfo; + } + + /// @notice Sets the current block number and timestamp of the L2 block. + /// @param _l2BlockNumber The number of the new L2 block. + /// @param _l2BlockTimestamp The timestamp of the new L2 block. + /// @param _prevL2BlockHash The hash of the previous L2 block. + function _setNewL2BlockData(uint128 _l2BlockNumber, uint128 _l2BlockTimestamp, bytes32 _prevL2BlockHash) internal { + // In the unsafe version we do not check that the block data is correct + currentL2BlockInfo = BlockInfo({number: _l2BlockNumber, timestamp: _l2BlockTimestamp}); + + // It is always assumed in production that _l2BlockNumber > 0 + _setL2BlockHash(_l2BlockNumber - 1, _prevL2BlockHash); + + // Reseting the rolling hash + currentL2BlockTxsRollingHash = bytes32(0); + } + + /// @notice Sets the current block number and timestamp of the L2 block. + /// @dev Called by the bootloader before each transaction. This is needed to ensure + /// that the data about the block is consistent with the sequencer. + /// @dev If the new block number is the same as the current one, we ensure that the block's data is + /// consistent with the one in the current block. + /// @dev If the new block number is greater than the current one by 1, + /// then we ensure that timestamp has increased. + /// @dev If the currently stored number is 0, we assume that it is the first upgrade transaction + /// and so we will fill up the old data. + /// @param _l2BlockNumber The number of the new L2 block. + /// @param _l2BlockTimestamp The timestamp of the new L2 block. + /// @param _expectedPrevL2BlockHash The expected hash of the previous L2 block. + /// @param _isFirstInBatch Whether this method is called for the first time in the batch. + /// @param _maxVirtualBlocksToCreate The maximum number of virtual block to create with this L2 block. + /// @dev It is a strict requirement that a new virtual block is created at the start of the batch. + /// @dev It is also enforced that the number of the current virtual L2 block can not exceed the number of the L2 block. + function setL2Block( + uint128 _l2BlockNumber, + uint128 _l2BlockTimestamp, + bytes32 _expectedPrevL2BlockHash, + bool _isFirstInBatch, + uint128 _maxVirtualBlocksToCreate + ) external onlyCallFromBootloader { + // We check that the timestamp of the L2 block is consistent with the timestamp of the batch. + if (_isFirstInBatch) { + uint128 currentBatchTimestamp = currentBatchInfo.timestamp; + require( + _l2BlockTimestamp >= currentBatchTimestamp, + "The timestamp of the L2 block must be greater than or equal to the timestamp of the current batch" + ); + require(_maxVirtualBlocksToCreate > 0, "There must be a virtual block created at the start of the batch"); + } + + (uint128 currentL2BlockNumber, uint128 currentL2BlockTimestamp) = getL2BlockNumberAndTimestamp(); + + if (currentL2BlockNumber == 0 && currentL2BlockTimestamp == 0) { + // Since currentL2BlockNumber and currentL2BlockTimestamp are zero it means that it is + // the first ever batch with L2 blocks, so we need to initialize those. + _upgradeL2Blocks(_l2BlockNumber, _expectedPrevL2BlockHash, _isFirstInBatch); + + _setNewL2BlockData(_l2BlockNumber, _l2BlockTimestamp, _expectedPrevL2BlockHash); + } else if (currentL2BlockNumber == _l2BlockNumber) { + require(!_isFirstInBatch, "Can not reuse L2 block number from the previous batch"); + require(currentL2BlockTimestamp == _l2BlockTimestamp, "The timestamp of the same L2 block must be same"); + require( + _expectedPrevL2BlockHash == _getLatest257L2blockHash(_l2BlockNumber - 1), + "The previous hash of the same L2 block must be same" + ); + require(_maxVirtualBlocksToCreate == 0, "Can not create virtual blocks in the middle of the miniblock"); + } else if (currentL2BlockNumber + 1 == _l2BlockNumber) { + // From the checks in _upgradeL2Blocks it is known that currentL2BlockNumber can not be 0 + bytes32 prevL2BlockHash = _getLatest257L2blockHash(currentL2BlockNumber - 1); + + bytes32 pendingL2BlockHash = _calculateL2BlockHash( + currentL2BlockNumber, + currentL2BlockTimestamp, + prevL2BlockHash, + currentL2BlockTxsRollingHash + ); + + require(_expectedPrevL2BlockHash == pendingL2BlockHash, "The current L2 block hash is incorrect"); + require( + _l2BlockTimestamp > currentL2BlockTimestamp, + "The timestamp of the new L2 block must be greater than the timestamp of the previous L2 block" + ); + + // Since the new block is created, we'll clear out the rolling hash + _setNewL2BlockData(_l2BlockNumber, _l2BlockTimestamp, _expectedPrevL2BlockHash); + } else { + revert("Invalid new L2 block number"); + } + + _setVirtualBlock(_l2BlockNumber, _maxVirtualBlocksToCreate, _l2BlockTimestamp); + } + + /// @notice Appends the transaction hash to the rolling hash of the current L2 block. + /// @param _txHash The hash of the transaction. + function appendTransactionToCurrentL2Block(bytes32 _txHash) external onlyCallFromBootloader { + currentL2BlockTxsRollingHash = keccak256(abi.encode(currentL2BlockTxsRollingHash, _txHash)); + } + + /// @notice Publishes L2->L1 logs needed to verify the validity of this batch on L1. + /// @dev Should be called at the end of the current batch. + function publishTimestampDataToL1() external onlyCallFromBootloader { + (uint128 currentBatchNumber, uint128 currentBatchTimestamp) = getBatchNumberAndTimestamp(); + (, uint128 currentL2BlockTimestamp) = getL2BlockNumberAndTimestamp(); + + // The structure of the "setNewBatch" implies that currentBatchNumber > 0, but we still double check it + require(currentBatchNumber > 0, "The current batch number must be greater than 0"); + + // In order to spend less pubdata, the packed version is published + uint256 packedTimestamps = (uint256(currentBatchTimestamp) << 128) | currentL2BlockTimestamp; + + SystemContractHelper.toL1( + false, + bytes32(uint256(SystemLogKey.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY)), + bytes32(packedTimestamps) + ); + } + + /// @notice Ensures that the timestamp of the batch is greater than the timestamp of the last L2 block. + /// @param _newTimestamp The timestamp of the new batch. + function _ensureBatchConsistentWithL2Block(uint128 _newTimestamp) internal view { + uint128 currentBlockTimestamp = currentL2BlockInfo.timestamp; + require( + _newTimestamp > currentBlockTimestamp, + "The timestamp of the batch must be greater than the timestamp of the previous block" + ); + } + + /// @notice Increments the current batch number and sets the new timestamp + /// @dev Called by the bootloader at the start of the batch. + /// @param _prevBatchHash The hash of the previous batch. + /// @param _newTimestamp The timestamp of the new batch. + /// @param _expectedNewNumber The new batch's number. + /// @param _baseFee The new batch's base fee + /// @dev While _expectedNewNumber can be derived as prevBatchNumber + 1, we still + /// manually supply it here for consistency checks. + /// @dev The correctness of the _prevBatchHash and _newTimestamp should be enforced on L1. + function setNewBatch( + bytes32 _prevBatchHash, + uint128 _newTimestamp, + uint128 _expectedNewNumber, + uint256 _baseFee + ) external onlyCallFromBootloader { + (uint128 previousBatchNumber, uint128 previousBatchTimestamp) = getBatchNumberAndTimestamp(); + require(_newTimestamp > previousBatchTimestamp, "Timestamps should be incremental"); + require(previousBatchNumber + 1 == _expectedNewNumber, "The provided block number is not correct"); + + _ensureBatchConsistentWithL2Block(_newTimestamp); + + batchHash[previousBatchNumber] = _prevBatchHash; + + // Setting new block number and timestamp + BlockInfo memory newBlockInfo = BlockInfo({number: previousBatchNumber + 1, timestamp: _newTimestamp}); + + currentBatchInfo = newBlockInfo; + + baseFee = _baseFee; + + // The correctness of this block hash: + SystemContractHelper.toL1(false, bytes32(uint256(SystemLogKey.PREV_BATCH_HASH_KEY)), _prevBatchHash); + } + + /// @notice A testing method that manually sets the current blocks' number and timestamp. + /// @dev Should be used only for testing / ethCalls and should never be used in production. + function unsafeOverrideBatch( + uint256 _newTimestamp, + uint256 _number, + uint256 _baseFee + ) external onlyCallFromBootloader { + BlockInfo memory newBlockInfo = BlockInfo({number: uint128(_number), timestamp: uint128(_newTimestamp)}); + currentBatchInfo = newBlockInfo; + + baseFee = _baseFee; + } + + function incrementTxNumberInBatch() external onlyCallFromBootloader { + txNumberInBlock += 1; + } + + function resetTxNumberInBatch() external onlyCallFromBootloader { + txNumberInBlock = 0; + } + + /*////////////////////////////////////////////////////////////// + DEPRECATED METHODS + //////////////////////////////////////////////////////////////*/ + + /// @notice Returns the current batch's number and timestamp. + /// @dev Deprecated in favor of getBatchNumberAndTimestamp. + function currentBlockInfo() external view returns (uint256 blockInfo) { + (uint128 blockNumber, uint128 blockTimestamp) = getBatchNumberAndTimestamp(); + blockInfo = (uint256(blockNumber) << 128) | uint256(blockTimestamp); + } + + /// @notice Returns the current batch's number and timestamp. + /// @dev Deprecated in favor of getBatchNumberAndTimestamp. + function getBlockNumberAndTimestamp() external view returns (uint256 blockNumber, uint256 blockTimestamp) { + (blockNumber, blockTimestamp) = getBatchNumberAndTimestamp(); + } + + /// @notice Returns the hash of the given batch. + /// @dev Deprecated in favor of getBatchHash. + function blockHash(uint256 _blockNumber) external view returns (bytes32 hash) { + hash = batchHash[_blockNumber]; + } +} diff --git a/system-contracts/contracts/interfaces/IAccount.sol b/system-contracts/contracts/interfaces/IAccount.sol new file mode 100644 index 000000000..3ee3f616c --- /dev/null +++ b/system-contracts/contracts/interfaces/IAccount.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "../libraries/TransactionHelper.sol"; + +bytes4 constant ACCOUNT_VALIDATION_SUCCESS_MAGIC = IAccount.validateTransaction.selector; + +interface IAccount { + /// @notice Called by the bootloader to validate that an account agrees to process the transaction + /// (and potentially pay for it). + /// @param _txHash The hash of the transaction to be used in the explorer + /// @param _suggestedSignedHash The hash of the transaction is signed by EOAs + /// @param _transaction The transaction itself + /// @return magic The magic value that should be equal to the signature of this function + /// if the user agrees to proceed with the transaction. + /// @dev The developer should strive to preserve as many steps as possible both for valid + /// and invalid transactions as this very method is also used during the gas fee estimation + /// (without some of the necessary data, e.g. signature). + function validateTransaction( + bytes32 _txHash, + bytes32 _suggestedSignedHash, + Transaction calldata _transaction + ) external payable returns (bytes4 magic); + + function executeTransaction( + bytes32 _txHash, + bytes32 _suggestedSignedHash, + Transaction calldata _transaction + ) external payable; + + // There is no point in providing possible signed hash in the `executeTransactionFromOutside` method, + // since it typically should not be trusted. + function executeTransactionFromOutside(Transaction calldata _transaction) external payable; + + function payForTransaction( + bytes32 _txHash, + bytes32 _suggestedSignedHash, + Transaction calldata _transaction + ) external payable; + + function prepareForPaymaster( + bytes32 _txHash, + bytes32 _possibleSignedHash, + Transaction calldata _transaction + ) external payable; +} diff --git a/system-contracts/contracts/interfaces/IAccountCodeStorage.sol b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol new file mode 100644 index 000000000..c266774ea --- /dev/null +++ b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +interface IAccountCodeStorage { + function storeAccountConstructingCodeHash(address _address, bytes32 _hash) external; + + function storeAccountConstructedCodeHash(address _address, bytes32 _hash) external; + + function markAccountCodeHashAsConstructed(address _address) external; + + function getRawCodeHash(address _address) external view returns (bytes32 codeHash); + + function getCodeHash(uint256 _input) external view returns (bytes32 codeHash); + + function getCodeSize(uint256 _input) external view returns (uint256 codeSize); +} diff --git a/system-contracts/contracts/interfaces/IBootloaderUtilities.sol b/system-contracts/contracts/interfaces/IBootloaderUtilities.sol new file mode 100644 index 000000000..e995295e1 --- /dev/null +++ b/system-contracts/contracts/interfaces/IBootloaderUtilities.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "../libraries/TransactionHelper.sol"; + +interface IBootloaderUtilities { + function getTransactionHashes( + Transaction calldata _transaction + ) external view returns (bytes32 txHash, bytes32 signedTxHash); +} diff --git a/system-contracts/contracts/interfaces/IComplexUpgrader.sol b/system-contracts/contracts/interfaces/IComplexUpgrader.sol new file mode 100644 index 000000000..ebc26dd20 --- /dev/null +++ b/system-contracts/contracts/interfaces/IComplexUpgrader.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +interface IComplexUpgrader { + function upgrade(address _delegateTo, bytes calldata _calldata) external payable; +} diff --git a/system-contracts/contracts/interfaces/ICompressor.sol b/system-contracts/contracts/interfaces/ICompressor.sol new file mode 100644 index 000000000..16e02d97f --- /dev/null +++ b/system-contracts/contracts/interfaces/ICompressor.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +// The bitmask by applying which to the compressed state diff metadata we retrieve its operation. +uint8 constant OPERATION_BITMASK = 7; +// The number of bits shifting the compressed state diff metadata by which we retrieve its length. +uint8 constant LENGTH_BITS_OFFSET = 3; +// The maximal length in bytes that an enumeration index can have. +uint8 constant MAX_ENUMERATION_INDEX_SIZE = 8; + +interface ICompressor { + function publishCompressedBytecode( + bytes calldata _bytecode, + bytes calldata _rawCompressedData + ) external payable returns (bytes32 bytecodeHash); + + function verifyCompressedStateDiffs( + uint256 _numberOfStateDiffs, + uint256 _enumerationIndexSize, + bytes calldata _stateDiffs, + bytes calldata _compressedStateDiffs + ) external payable returns (bytes32 stateDiffHash); +} diff --git a/system-contracts/contracts/interfaces/IContractDeployer.sol b/system-contracts/contracts/interfaces/IContractDeployer.sol new file mode 100644 index 000000000..3f84672d7 --- /dev/null +++ b/system-contracts/contracts/interfaces/IContractDeployer.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +interface IContractDeployer { + /// @notice Defines the version of the account abstraction protocol + /// that a contract claims to follow. + /// - `None` means that the account is just a contract and it should never be interacted + /// with as a custom account + /// - `Version1` means that the account follows the first version of the account abstraction protocol + enum AccountAbstractionVersion { + None, + Version1 + } + + /// @notice Defines the nonce ordering used by the account + /// - `Sequential` means that it is expected that the nonces are monotonic and increment by 1 + /// at a time (the same as EOAs). + /// - `Arbitrary` means that the nonces for the accounts can be arbitrary. The operator + /// should serve the transactions from such an account on a first-come-first-serve basis. + /// @dev This ordering is more of a suggestion to the operator on how the AA expects its transactions + /// to be processed and is not considered as a system invariant. + enum AccountNonceOrdering { + Sequential, + Arbitrary + } + + struct AccountInfo { + AccountAbstractionVersion supportedAAVersion; + AccountNonceOrdering nonceOrdering; + } + + event ContractDeployed( + address indexed deployerAddress, + bytes32 indexed bytecodeHash, + address indexed contractAddress + ); + + event AccountNonceOrderingUpdated(address indexed accountAddress, AccountNonceOrdering nonceOrdering); + + event AccountVersionUpdated(address indexed accountAddress, AccountAbstractionVersion aaVersion); + + function getNewAddressCreate2( + address _sender, + bytes32 _bytecodeHash, + bytes32 _salt, + bytes calldata _input + ) external view returns (address newAddress); + + function getNewAddressCreate(address _sender, uint256 _senderNonce) external pure returns (address newAddress); + + function create2( + bytes32 _salt, + bytes32 _bytecodeHash, + bytes calldata _input + ) external payable returns (address newAddress); + + function create2Account( + bytes32 _salt, + bytes32 _bytecodeHash, + bytes calldata _input, + AccountAbstractionVersion _aaVersion + ) external payable returns (address newAddress); + + /// @dev While the `_salt` parameter is not used anywhere here, + /// it is still needed for consistency between `create` and + /// `create2` functions (required by the compiler). + function create( + bytes32 _salt, + bytes32 _bytecodeHash, + bytes calldata _input + ) external payable returns (address newAddress); + + /// @dev While `_salt` is never used here, we leave it here as a parameter + /// for the consistency with the `create` function. + function createAccount( + bytes32 _salt, + bytes32 _bytecodeHash, + bytes calldata _input, + AccountAbstractionVersion _aaVersion + ) external payable returns (address newAddress); + + /// @notice Returns the information about a certain AA. + function getAccountInfo(address _address) external view returns (AccountInfo memory info); + + /// @notice Can be called by an account to update its account version + function updateAccountVersion(AccountAbstractionVersion _version) external; + + /// @notice Can be called by an account to update its nonce ordering + function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external; +} diff --git a/system-contracts/contracts/interfaces/IEthToken.sol b/system-contracts/contracts/interfaces/IEthToken.sol new file mode 100644 index 000000000..ec9b399f5 --- /dev/null +++ b/system-contracts/contracts/interfaces/IEthToken.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +interface IEthToken { + function balanceOf(uint256) external view returns (uint256); + + function transferFromTo(address _from, address _to, uint256 _amount) external; + + function totalSupply() external view returns (uint256); + + function name() external pure returns (string memory); + + function symbol() external pure returns (string memory); + + function decimals() external pure returns (uint8); + + function mint(address _account, uint256 _amount) external; + + function withdraw(address _l1Receiver) external payable; + + function withdrawWithMessage(address _l1Receiver, bytes calldata _additionalData) external payable; + + event Mint(address indexed account, uint256 amount); + + event Transfer(address indexed from, address indexed to, uint256 value); + + event Withdrawal(address indexed _l2Sender, address indexed _l1Receiver, uint256 _amount); + + event WithdrawalWithMessage( + address indexed _l2Sender, + address indexed _l1Receiver, + uint256 _amount, + bytes _additionalData + ); +} diff --git a/system-contracts/contracts/interfaces/IImmutableSimulator.sol b/system-contracts/contracts/interfaces/IImmutableSimulator.sol new file mode 100644 index 000000000..d30ac9b96 --- /dev/null +++ b/system-contracts/contracts/interfaces/IImmutableSimulator.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +struct ImmutableData { + uint256 index; + bytes32 value; +} + +interface IImmutableSimulator { + function getImmutable(address _dest, uint256 _index) external view returns (bytes32); + + function setImmutables(address _dest, ImmutableData[] calldata _immutables) external; +} diff --git a/system-contracts/contracts/interfaces/IKnownCodesStorage.sol b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol new file mode 100644 index 000000000..b5a783baa --- /dev/null +++ b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +interface IKnownCodesStorage { + event MarkedAsKnown(bytes32 indexed bytecodeHash, bool indexed sendBytecodeToL1); + + function markFactoryDeps(bool _shouldSendToL1, bytes32[] calldata _hashes) external; + + function markBytecodeAsPublished(bytes32 _bytecodeHash) external; + + function getMarker(bytes32 _hash) external view returns (uint256); +} diff --git a/system-contracts/contracts/interfaces/IL1Messenger.sol b/system-contracts/contracts/interfaces/IL1Messenger.sol new file mode 100644 index 000000000..ab6a670f9 --- /dev/null +++ b/system-contracts/contracts/interfaces/IL1Messenger.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/// @dev The log passed from L2 +/// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter. All other values are not used but are reserved for the future +/// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address. +/// This field is required formally but does not have any special meaning. +/// @param txNumberInBlock The L2 transaction number in a block, in which the log was sent +/// @param sender The L2 address which sent the log +/// @param key The 32 bytes of information that was sent in the log +/// @param value The 32 bytes of information that was sent in the log +// Both `key` and `value` are arbitrary 32-bytes selected by the log sender +struct L2ToL1Log { + uint8 l2ShardId; + bool isService; + uint16 txNumberInBlock; + address sender; + bytes32 key; + bytes32 value; +} + +/// @dev Bytes in raw L2 to L1 log +/// @dev Equal to the bytes size of the tuple - (uint8 ShardId, bool isService, uint16 txNumberInBlock, address sender, bytes32 key, bytes32 value) +uint256 constant L2_TO_L1_LOG_SERIALIZE_SIZE = 88; + +/// @dev The value of default leaf hash for L2 to L1 logs Merkle tree +/// @dev An incomplete fixed-size tree is filled with this value to be a full binary tree +/// @dev Actually equal to the `keccak256(new bytes(L2_TO_L1_LOG_SERIALIZE_SIZE))` +bytes32 constant L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH = 0x72abee45b59e344af8a6e520241c4744aff26ed411f4c4b00f8af09adada43ba; + +/// @dev The current version of state diff compression being used. +uint256 constant STATE_DIFF_COMPRESSION_VERSION_NUMBER = 1; + +interface IL1Messenger { + // Possibly in the future we will be able to track the messages sent to L1 with + // some hooks in the VM. For now, it is much easier to track them with L2 events. + event L1MessageSent(address indexed _sender, bytes32 indexed _hash, bytes _message); + + event L2ToL1LogSent(L2ToL1Log _l2log); + + event BytecodeL1PublicationRequested(bytes32 _bytecodeHash); + + function sendToL1(bytes memory _message) external returns (bytes32); + + function sendL2ToL1Log(bool _isService, bytes32 _key, bytes32 _value) external returns (uint256 logIdInMerkleTree); + + // This function is expected to be called only by the KnownCodesStorage system contract + function requestBytecodeL1Publication(bytes32 _bytecodeHash) external; +} diff --git a/system-contracts/contracts/interfaces/IL2StandardToken.sol b/system-contracts/contracts/interfaces/IL2StandardToken.sol new file mode 100644 index 000000000..3d75c8ede --- /dev/null +++ b/system-contracts/contracts/interfaces/IL2StandardToken.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +interface IL2StandardToken { + event BridgeMint(address indexed _account, uint256 _amount); + + event BridgeBurn(address indexed _account, uint256 _amount); + + function bridgeMint(address _account, uint256 _amount) external; + + function bridgeBurn(address _account, uint256 _amount) external; + + function l1Address() external view returns (address); + + function l2Bridge() external view returns (address); +} diff --git a/system-contracts/contracts/interfaces/IMailbox.sol b/system-contracts/contracts/interfaces/IMailbox.sol new file mode 100644 index 000000000..ba673058c --- /dev/null +++ b/system-contracts/contracts/interfaces/IMailbox.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +interface IMailbox { + function finalizeEthWithdrawal( + uint256 _l2BatchNumber, + uint256 _l2MessageIndex, + uint16 _l2TxNumberInBlock, + bytes calldata _message, + bytes32[] calldata _merkleProof + ) external; +} diff --git a/system-contracts/contracts/interfaces/INonceHolder.sol b/system-contracts/contracts/interfaces/INonceHolder.sol new file mode 100644 index 000000000..1213fbea4 --- /dev/null +++ b/system-contracts/contracts/interfaces/INonceHolder.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @dev Interface of the nonce holder contract -- a contract used by the system to ensure + * that there is always a unique identifier for a transaction with a particular account (we call it nonce). + * In other words, the pair of (address, nonce) should always be unique. + * @dev Custom accounts should use methods of this contract to store nonces or other possible unique identifiers + * for the transaction. + */ +interface INonceHolder { + event ValueSetUnderNonce(address indexed accountAddress, uint256 indexed key, uint256 value); + + /// @dev Returns the current minimal nonce for account. + function getMinNonce(address _address) external view returns (uint256); + + /// @dev Returns the raw version of the current minimal nonce + /// (equal to minNonce + 2^128 * deployment nonce). + function getRawNonce(address _address) external view returns (uint256); + + /// @dev Increases the minimal nonce for the msg.sender. + function increaseMinNonce(uint256 _value) external returns (uint256); + + /// @dev Sets the nonce value `key` as used. + function setValueUnderNonce(uint256 _key, uint256 _value) external; + + /// @dev Gets the value stored inside a custom nonce. + function getValueUnderNonce(uint256 _key) external view returns (uint256); + + /// @dev A convenience method to increment the minimal nonce if it is equal + /// to the `_expectedNonce`. + function incrementMinNonceIfEquals(uint256 _expectedNonce) external; + + /// @dev Returns the deployment nonce for the accounts used for CREATE opcode. + function getDeploymentNonce(address _address) external view returns (uint256); + + /// @dev Increments the deployment nonce for the account and returns the previous one. + function incrementDeploymentNonce(address _address) external returns (uint256); + + /// @dev Determines whether a certain nonce has been already used for an account. + function validateNonceUsage(address _address, uint256 _key, bool _shouldBeUsed) external view; + + /// @dev Returns whether a nonce has been used for an account. + function isNonceUsed(address _address, uint256 _nonce) external view returns (bool); +} diff --git a/system-contracts/contracts/interfaces/IPaymaster.sol b/system-contracts/contracts/interfaces/IPaymaster.sol new file mode 100644 index 000000000..928f19eda --- /dev/null +++ b/system-contracts/contracts/interfaces/IPaymaster.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "../libraries/TransactionHelper.sol"; + +enum ExecutionResult { + Revert, + Success +} + +bytes4 constant PAYMASTER_VALIDATION_SUCCESS_MAGIC = IPaymaster.validateAndPayForPaymasterTransaction.selector; + +interface IPaymaster { + /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the + /// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader + /// address. + /// @param _txHash The hash of the transaction + /// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA + /// @param _transaction The transaction itself. + /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction + /// if the paymaster agrees to pay for the transaction. + /// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be + /// passed to the `postTransaction` method of the account. + /// @dev The developer should strive to preserve as many steps as possible both for valid + /// and invalid transactions as this very method is also used during the gas fee estimation + /// (without some of the necessary data, e.g. signature). + function validateAndPayForPaymasterTransaction( + bytes32 _txHash, + bytes32 _suggestedSignedHash, + Transaction calldata _transaction + ) external payable returns (bytes4 magic, bytes memory context); + + /// @dev Called by the bootloader after the execution of the transaction. Please note that + /// there is no guarantee that this method will be called at all. Unlike the original EIP4337, + /// this method won't be called if the transaction execution results in out-of-gas. + /// @param _context, the context of the execution, returned by the "validateAndPayForPaymasterTransaction" method. + /// @param _transaction, the users' transaction. + /// @param _txResult, the result of the transaction execution (success or failure). + /// @param _maxRefundedGas, the upper bound on the amout of gas that could be refunded to the paymaster. + /// @dev The exact amount refunded depends on the gas spent by the "postOp" itself and so the developers should + /// take that into account. + function postTransaction( + bytes calldata _context, + Transaction calldata _transaction, + bytes32 _txHash, + bytes32 _suggestedSignedHash, + ExecutionResult _txResult, + uint256 _maxRefundedGas + ) external payable; +} diff --git a/system-contracts/contracts/interfaces/IPaymasterFlow.sol b/system-contracts/contracts/interfaces/IPaymasterFlow.sol new file mode 100644 index 000000000..59352f23b --- /dev/null +++ b/system-contracts/contracts/interfaces/IPaymasterFlow.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @dev The interface that is used for encoding/decoding of + * different types of paymaster flows. + * @notice This is NOT an interface to be implementated + * by contracts. It is just used for encoding. + */ +interface IPaymasterFlow { + function general(bytes calldata input) external; + + function approvalBased(address _token, uint256 _minAllowance, bytes calldata _innerInput) external; +} diff --git a/system-contracts/contracts/interfaces/ISystemContext.sol b/system-contracts/contracts/interfaces/ISystemContext.sol new file mode 100644 index 000000000..d8a98292a --- /dev/null +++ b/system-contracts/contracts/interfaces/ISystemContext.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @notice Contract that stores some of the context variables, that may be either + * block-scoped, tx-scoped or system-wide. + */ +interface ISystemContext { + struct BlockInfo { + uint128 timestamp; + uint128 number; + } + + /// @notice A structure representing the timeline for the upgrade from the batch numbers to the L2 block numbers. + /// @dev It will used for the L1 batch -> L2 block migration in Q3 2023 only. + struct VirtualBlockUpgradeInfo { + /// @notice In order to maintain consistent results for `blockhash` requests, we'll + /// have to remember the number of the batch when the upgrade to the virtual blocks has been done. + /// The hashes for virtual blocks before the upgrade are identical to the hashes of the corresponding batches. + uint128 virtualBlockStartBatch; + /// @notice L2 block when the virtual blocks have caught up with the L2 blocks. Starting from this block, + /// all the information returned to users for block.timestamp/number, etc should be the information about the L2 blocks and + /// not virtual blocks. + uint128 virtualBlockFinishL2Block; + } + + function chainId() external view returns (uint256); + + function origin() external view returns (address); + + function gasPrice() external view returns (uint256); + + function blockGasLimit() external view returns (uint256); + + function coinbase() external view returns (address); + + function difficulty() external view returns (uint256); + + function baseFee() external view returns (uint256); + + function txNumberInBlock() external view returns (uint16); + + function getBlockHashEVM(uint256 _block) external view returns (bytes32); + + function getBatchHash(uint256 _batchNumber) external view returns (bytes32 hash); + + function getBlockNumber() external view returns (uint128); + + function getBlockTimestamp() external view returns (uint128); + + function getBatchNumberAndTimestamp() external view returns (uint128 blockNumber, uint128 blockTimestamp); + + function getL2BlockNumberAndTimestamp() external view returns (uint128 blockNumber, uint128 blockTimestamp); +} diff --git a/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol b/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol new file mode 100644 index 000000000..b51faeeda --- /dev/null +++ b/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @notice The interface with deprecated functions of the SystemContext contract. It is aimed for backward compatibility. + */ +interface ISystemContextDeprecated { + function currentBlockInfo() external view returns (uint256); + + function getBlockNumberAndTimestamp() external view returns (uint256 blockNumber, uint256 blockTimestamp); + + function blockHash(uint256 _blockNumber) external view returns (bytes32 hash); +} diff --git a/system-contracts/contracts/interfaces/ISystemContract.sol b/system-contracts/contracts/interfaces/ISystemContract.sol new file mode 100644 index 000000000..c486abc96 --- /dev/null +++ b/system-contracts/contracts/interfaces/ISystemContract.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {SystemContractHelper} from "../libraries/SystemContractHelper.sol"; +import {BOOTLOADER_FORMAL_ADDRESS} from "../Constants.sol"; + +/// @dev Solidity does not allow exporting modifiers via libraries, so +/// the only way to do reuse modifiers is to have a base contract +/// @dev Never add storage variables into this contract as some +/// system contracts rely on this abstract contract as on interface! +abstract contract ISystemContract { + /// @notice Modifier that makes sure that the method + /// can only be called via a system call. + modifier onlySystemCall() { + require( + SystemContractHelper.isSystemCall() || SystemContractHelper.isSystemContract(msg.sender), + "This method require system call flag" + ); + _; + } + + /// @notice Modifier that makes sure that the method + /// can only be called from a system contract. + modifier onlyCallFromSystemContract() { + require( + SystemContractHelper.isSystemContract(msg.sender), + "This method require the caller to be system contract" + ); + _; + } + + /// @notice Modifier that makes sure that the method + /// can only be called from a special given address. + modifier onlyCallFrom(address caller) { + require(msg.sender == caller, "Inappropriate caller"); + _; + } + + /// @notice Modifier that makes sure that the method + /// can only be called from the bootloader. + modifier onlyCallFromBootloader() { + require(msg.sender == BOOTLOADER_FORMAL_ADDRESS, "Callable only by the bootloader"); + _; + } +} diff --git a/system-contracts/contracts/libraries/EfficientCall.sol b/system-contracts/contracts/libraries/EfficientCall.sol new file mode 100644 index 000000000..22801d6f7 --- /dev/null +++ b/system-contracts/contracts/libraries/EfficientCall.sol @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "./SystemContractHelper.sol"; +import "./Utils.sol"; +import {SHA256_SYSTEM_CONTRACT, KECCAK256_SYSTEM_CONTRACT, MSG_VALUE_SYSTEM_CONTRACT} from "../Constants.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice This library is used to perform ultra-efficient calls using zkEVM-specific features. + * @dev EVM calls always accept a memory slice as input and return a memory slice as output. + * Therefore, even if the user has a ready-made calldata slice, they still need to copy it to memory + * before calling. This is especially inefficient for large inputs (proxies, multi-calls, etc.). + * In turn, zkEVM operates over a fat pointer, which is a set of (memory page, offset, start, length) in the memory/calldata/returndata. + * This allows forwarding the calldata slice as is, without copying it to memory. + * @dev Fat pointer is not just an integer, it is an extended data type supported on the VM level. + * zkEVM creates the wellformed fat pointers for all the calldata/returndata regions, later + * the contract may manipulate the already created fat pointers to forward a slice of the data, but not + * to create new fat pointers! + * @dev The allowed operation on fat pointers are: + * 1. `ptr.add` - Transforms `ptr.offset` into `ptr.offset + u32(_value)`. If overflow happens then it panics. + * 2. `ptr.sub` - Transforms `ptr.offset` into `ptr.offset - u32(_value)`. If underflow happens then it panics. + * 3. `ptr.pack` - Do the concatenation between the lowest 128 bits of the pointer itself and the highest 128 bits of `_value`. It is typically used to prepare the ABI for external calls. + * 4. `ptr.shrink` - Transforms `ptr.length` into `ptr.length - u32(_shrink)`. If underflow happens then it panics. + * @dev The call opcodes accept the fat pointer and change it to its canonical form before passing it to the child call + * 1. `ptr.start` is transformed into `ptr.offset + ptr.start` + * 2. `ptr.length` is transformed into `ptr.length - ptr.offset` + * 3. `ptr.offset` is transformed into `0` + */ +library EfficientCall { + /// @notice Call the `keccak256` without copying calldata to memory. + /// @param _data The preimage data. + /// @return The `keccak256` hash. + function keccak(bytes calldata _data) internal view returns (bytes32) { + bytes memory returnData = staticCall(gasleft(), KECCAK256_SYSTEM_CONTRACT, _data); + require(returnData.length == 32, "keccak256 returned invalid data"); + return bytes32(returnData); + } + + /// @notice Call the `sha256` precompile without copying calldata to memory. + /// @param _data The preimage data. + /// @return The `sha256` hash. + function sha(bytes calldata _data) internal view returns (bytes32) { + bytes memory returnData = staticCall(gasleft(), SHA256_SYSTEM_CONTRACT, _data); + require(returnData.length == 32, "sha returned invalid data"); + return bytes32(returnData); + } + + /// @notice Perform a `call` without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _value The `msg.value` to send. + /// @param _data The calldata to use for the call. + /// @param _isSystem Whether the call should contain the `isSystem` flag. + /// @return returnData The copied to memory return data. + function call( + uint256 _gas, + address _address, + uint256 _value, + bytes calldata _data, + bool _isSystem + ) internal returns (bytes memory returnData) { + bool success = rawCall(_gas, _address, _value, _data, _isSystem); + returnData = _verifyCallResult(success); + } + + /// @notice Perform a `staticCall` without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _data The calldata to use for the call. + /// @return returnData The copied to memory return data. + function staticCall( + uint256 _gas, + address _address, + bytes calldata _data + ) internal view returns (bytes memory returnData) { + bool success = rawStaticCall(_gas, _address, _data); + returnData = _verifyCallResult(success); + } + + /// @notice Perform a `delegateCall` without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _data The calldata to use for the call. + /// @return returnData The copied to memory return data. + function delegateCall( + uint256 _gas, + address _address, + bytes calldata _data + ) internal returns (bytes memory returnData) { + bool success = rawDelegateCall(_gas, _address, _data); + returnData = _verifyCallResult(success); + } + + /// @notice Perform a `mimicCall` (a call with custom msg.sender) without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _data The calldata to use for the call. + /// @param _whoToMimic The `msg.sender` for the next call. + /// @param _isConstructor Whether the call should contain the `isConstructor` flag. + /// @param _isSystem Whether the call should contain the `isSystem` flag. + /// @return returnData The copied to memory return data. + function mimicCall( + uint256 _gas, + address _address, + bytes calldata _data, + address _whoToMimic, + bool _isConstructor, + bool _isSystem + ) internal returns (bytes memory returnData) { + bool success = rawMimicCall(_gas, _address, _data, _whoToMimic, _isConstructor, _isSystem); + returnData = _verifyCallResult(success); + } + + /// @notice Perform a `call` without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _value The `msg.value` to send. + /// @param _data The calldata to use for the call. + /// @param _isSystem Whether the call should contain the `isSystem` flag. + /// @return success whether the call was successful. + function rawCall( + uint256 _gas, + address _address, + uint256 _value, + bytes calldata _data, + bool _isSystem + ) internal returns (bool success) { + if (_value == 0) { + _loadFarCallABIIntoActivePtr(_gas, _data, false, _isSystem); + + address callAddr = RAW_FAR_CALL_BY_REF_CALL_ADDRESS; + assembly { + success := call(_address, callAddr, 0, 0, 0xFFFF, 0, 0) + } + } else { + _loadFarCallABIIntoActivePtr(_gas, _data, false, true); + + // If there is provided `msg.value` call the `MsgValueSimulator` to forward ether. + address msgValueSimulator = MSG_VALUE_SYSTEM_CONTRACT; + address callAddr = SYSTEM_CALL_BY_REF_CALL_ADDRESS; + // We need to supply the mask to the MsgValueSimulator to denote + // that the call should be a system one. + uint256 forwardMask = _isSystem ? MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT : 0; + + assembly { + success := call(msgValueSimulator, callAddr, _value, _address, 0xFFFF, forwardMask, 0) + } + } + } + + /// @notice Perform a `staticCall` without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _data The calldata to use for the call. + /// @return success whether the call was successful. + function rawStaticCall(uint256 _gas, address _address, bytes calldata _data) internal view returns (bool success) { + _loadFarCallABIIntoActivePtr(_gas, _data, false, false); + + address callAddr = RAW_FAR_CALL_BY_REF_CALL_ADDRESS; + assembly { + success := staticcall(_address, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Perform a `delegatecall` without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _data The calldata to use for the call. + /// @return success whether the call was successful. + function rawDelegateCall(uint256 _gas, address _address, bytes calldata _data) internal returns (bool success) { + _loadFarCallABIIntoActivePtr(_gas, _data, false, false); + + address callAddr = RAW_FAR_CALL_BY_REF_CALL_ADDRESS; + assembly { + success := delegatecall(_address, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Perform a `mimicCall` (call with custom msg.sender) without copying calldata to memory. + /// @param _gas The gas to use for the call. + /// @param _address The address to call. + /// @param _data The calldata to use for the call. + /// @param _whoToMimic The `msg.sender` for the next call. + /// @param _isConstructor Whether the call should contain the `isConstructor` flag. + /// @param _isSystem Whether the call should contain the `isSystem` flag. + /// @return success whether the call was successful. + /// @dev If called not in kernel mode, it will result in a revert (enforced by the VM) + function rawMimicCall( + uint256 _gas, + address _address, + bytes calldata _data, + address _whoToMimic, + bool _isConstructor, + bool _isSystem + ) internal returns (bool success) { + _loadFarCallABIIntoActivePtr(_gas, _data, _isConstructor, _isSystem); + + address callAddr = MIMIC_CALL_BY_REF_CALL_ADDRESS; + uint256 cleanupMask = ADDRESS_MASK; + assembly { + // Clearing values before usage in assembly, since Solidity + // doesn't do it by default + _whoToMimic := and(_whoToMimic, cleanupMask) + + success := call(_address, callAddr, 0, 0, _whoToMimic, 0, 0) + } + } + + /// @dev Verify that a low-level call was successful, and revert if it wasn't, by bubbling the revert reason. + /// @param _success Whether the call was successful. + /// @return returnData The copied to memory return data. + function _verifyCallResult(bool _success) private pure returns (bytes memory returnData) { + if (_success) { + uint256 size; + assembly { + size := returndatasize() + } + + returnData = new bytes(size); + assembly { + returndatacopy(add(returnData, 0x20), 0, size) + } + } else { + propagateRevert(); + } + } + + /// @dev Propagate the revert reason from the current call to the caller. + function propagateRevert() internal pure { + assembly { + let size := returndatasize() + returndatacopy(0, 0, size) + revert(0, size) + } + } + + /// @dev Load the far call ABI into active ptr, that will be used for the next call by reference. + /// @param _gas The gas to be passed to the call. + /// @param _data The calldata to be passed to the call. + /// @param _isConstructor Whether the call is a constructor call. + /// @param _isSystem Whether the call is a system call. + function _loadFarCallABIIntoActivePtr( + uint256 _gas, + bytes calldata _data, + bool _isConstructor, + bool _isSystem + ) private view { + SystemContractHelper.loadCalldataIntoActivePtr(); + + uint256 dataOffset; + assembly { + dataOffset := _data.offset + } + + // Safe to cast, offset is never bigger than `type(uint32).max` + SystemContractHelper.ptrAddIntoActive(uint32(dataOffset)); + // Safe to cast, `data.length` is never bigger than `type(uint32).max` + uint32 shrinkTo = uint32(msg.data.length - (_data.length + dataOffset)); + SystemContractHelper.ptrShrinkIntoActive(shrinkTo); + + uint32 gas = Utils.safeCastToU32(_gas); + uint256 farCallAbi = SystemContractsCaller.getFarCallABIWithEmptyFatPointer( + gas, + // Only rollup is supported for now + 0, + CalldataForwardingMode.ForwardFatPointer, + _isConstructor, + _isSystem + ); + SystemContractHelper.ptrPackIntoActivePtr(farCallAbi); + } +} diff --git a/system-contracts/contracts/libraries/RLPEncoder.sol b/system-contracts/contracts/libraries/RLPEncoder.sol new file mode 100644 index 000000000..8e32ea9ba --- /dev/null +++ b/system-contracts/contracts/libraries/RLPEncoder.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice This library provides RLP encoding functionality. + */ +library RLPEncoder { + function encodeAddress(address _val) internal pure returns (bytes memory encoded) { + // The size is equal to 20 bytes of the address itself + 1 for encoding bytes length in RLP. + encoded = new bytes(0x15); + + bytes20 shiftedVal = bytes20(_val); + assembly { + // In the first byte we write the encoded length as 0x80 + 0x14 == 0x94. + mstore(add(encoded, 0x20), 0x9400000000000000000000000000000000000000000000000000000000000000) + // Write address data without stripping zeros. + mstore(add(encoded, 0x21), shiftedVal) + } + } + + function encodeUint256(uint256 _val) internal pure returns (bytes memory encoded) { + unchecked { + if (_val < 128) { + encoded = new bytes(1); + // Handle zero as a non-value, since stripping zeroes results in an empty byte array + encoded[0] = (_val == 0) ? bytes1(uint8(128)) : bytes1(uint8(_val)); + } else { + uint256 hbs = _highestByteSet(_val); + + encoded = new bytes(hbs + 2); + encoded[0] = bytes1(uint8(hbs + 0x81)); + + uint256 lbs = 31 - hbs; + uint256 shiftedVal = _val << (lbs * 8); + + assembly { + mstore(add(encoded, 0x21), shiftedVal) + } + } + } + } + + /// @notice Encodes the size of bytes in RLP format. + /// @param _len The length of the bytes to encode. It has a `uint64` type since as larger values are not supported. + /// NOTE: panics if the length is 1 since the length encoding is ambiguous in this case. + function encodeNonSingleBytesLen(uint64 _len) internal pure returns (bytes memory) { + assert(_len != 1); + return _encodeLength(_len, 0x80); + } + + /// @notice Encodes the size of list items in RLP format. + /// @param _len The length of the bytes to encode. It has a `uint64` type since as larger values are not supported. + function encodeListLen(uint64 _len) internal pure returns (bytes memory) { + return _encodeLength(_len, 0xc0); + } + + function _encodeLength(uint64 _len, uint256 _offset) private pure returns (bytes memory encoded) { + unchecked { + if (_len < 56) { + encoded = new bytes(1); + encoded[0] = bytes1(uint8(_len + _offset)); + } else { + uint256 hbs = _highestByteSet(uint256(_len)); + + encoded = new bytes(hbs + 2); + encoded[0] = bytes1(uint8(_offset + hbs + 56)); + + uint256 lbs = 31 - hbs; + uint256 shiftedVal = uint256(_len) << (lbs * 8); + + assembly { + mstore(add(encoded, 0x21), shiftedVal) + } + } + } + } + + /// @notice Computes the index of the highest byte set in number. + /// @notice Uses little endian ordering (The least significant byte has index `0`). + /// NOTE: returns `0` for `0` + function _highestByteSet(uint256 _number) private pure returns (uint256 hbs) { + unchecked { + if (_number > type(uint128).max) { + _number >>= 128; + hbs += 16; + } + if (_number > type(uint64).max) { + _number >>= 64; + hbs += 8; + } + if (_number > type(uint32).max) { + _number >>= 32; + hbs += 4; + } + if (_number > type(uint16).max) { + _number >>= 16; + hbs += 2; + } + if (_number > type(uint8).max) { + hbs += 1; + } + } + } +} diff --git a/system-contracts/contracts/libraries/SystemContractHelper.sol b/system-contracts/contracts/libraries/SystemContractHelper.sol new file mode 100644 index 000000000..a66b96706 --- /dev/null +++ b/system-contracts/contracts/libraries/SystemContractHelper.sol @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {MAX_SYSTEM_CONTRACT_ADDRESS} from "../Constants.sol"; + +import {SystemContractsCaller, CalldataForwardingMode, CALLFLAGS_CALL_ADDRESS, CODE_ADDRESS_CALL_ADDRESS, EVENT_WRITE_ADDRESS, EVENT_INITIALIZE_ADDRESS, GET_EXTRA_ABI_DATA_ADDRESS, LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS, META_CODE_SHARD_ID_OFFSET, META_CALLER_SHARD_ID_OFFSET, META_SHARD_ID_OFFSET, META_AUX_HEAP_SIZE_OFFSET, META_HEAP_SIZE_OFFSET, META_GAS_PER_PUBDATA_BYTE_OFFSET, MIMIC_CALL_BY_REF_CALL_ADDRESS, META_CALL_ADDRESS, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, PTR_CALLDATA_CALL_ADDRESS, PTR_ADD_INTO_ACTIVE_CALL_ADDRESS, PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS, PTR_PACK_INTO_ACTIVE_CALL_ADDRESS, RAW_FAR_CALL_BY_REF_CALL_ADDRESS, PRECOMPILE_CALL_ADDRESS, SET_CONTEXT_VALUE_CALL_ADDRESS, SYSTEM_CALL_BY_REF_CALL_ADDRESS, TO_L1_CALL_ADDRESS} from "./SystemContractsCaller.sol"; + +uint256 constant UINT32_MASK = 0xffffffff; +uint256 constant UINT128_MASK = 0xffffffffffffffffffffffffffffffff; +/// @dev The mask that is used to convert any uint256 to a proper address. +/// It needs to be padded with `00` to be treated as uint256 by Solidity +uint256 constant ADDRESS_MASK = 0x00ffffffffffffffffffffffffffffffffffffffff; + +struct ZkSyncMeta { + uint32 gasPerPubdataByte; + uint32 heapSize; + uint32 auxHeapSize; + uint8 shardId; + uint8 callerShardId; + uint8 codeShardId; +} + +enum Global { + CalldataPtr, + CallFlags, + ExtraABIData1, + ExtraABIData2, + ReturndataPtr +} + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Library used for accessing zkEVM-specific opcodes, needed for the development + * of system contracts. + * @dev While this library will be eventually available to public, some of the provided + * methods won't work for non-system contracts. We will not recommend this library + * for external use. + */ +library SystemContractHelper { + /// @notice Send an L2Log to L1. + /// @param _isService The `isService` flag. + /// @param _key The `key` part of the L2Log. + /// @param _value The `value` part of the L2Log. + /// @dev The meaning of all these parameters is context-dependent, but they + /// have no intrinsic meaning per se. + function toL1(bool _isService, bytes32 _key, bytes32 _value) internal { + address callAddr = TO_L1_CALL_ADDRESS; + assembly { + // Ensuring that the type is bool + _isService := and(_isService, 1) + // This `success` is always 0, but the method always succeeds + // (except for the cases when there is not enough gas) + let success := call(_isService, callAddr, _key, _value, 0xFFFF, 0, 0) + } + } + + /// @notice Get address of the currently executed code. + /// @dev This allows differentiating between `call` and `delegatecall`. + /// During the former `this` and `codeAddress` are the same, while + /// during the latter they are not. + function getCodeAddress() internal view returns (address addr) { + address callAddr = CODE_ADDRESS_CALL_ADDRESS; + assembly { + addr := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Provide a compiler hint, by placing calldata fat pointer into virtual `ACTIVE_PTR`, + /// that can be manipulated by `ptr.add`/`ptr.sub`/`ptr.pack`/`ptr.shrink` later. + /// @dev This allows making a call by forwarding calldata pointer to the child call. + /// It is a much more efficient way to forward calldata, than standard EVM bytes copying. + function loadCalldataIntoActivePtr() internal view { + address callAddr = LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS; + assembly { + pop(staticcall(0, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Compiler simulation of the `ptr.pack` opcode for the virtual `ACTIVE_PTR` pointer. + /// @dev Do the concatenation between lowest part of `ACTIVE_PTR` and highest part of `_farCallAbi` + /// forming packed fat pointer for a far call or ret ABI when necessary. + /// Note: Panics if the lowest 128 bits of `_farCallAbi` are not zeroes. + function ptrPackIntoActivePtr(uint256 _farCallAbi) internal view { + address callAddr = PTR_PACK_INTO_ACTIVE_CALL_ADDRESS; + assembly { + pop(staticcall(_farCallAbi, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Compiler simulation of the `ptr.add` opcode for the virtual `ACTIVE_PTR` pointer. + /// @dev Transforms `ACTIVE_PTR.offset` into `ACTIVE_PTR.offset + u32(_value)`. If overflow happens then it panics. + function ptrAddIntoActive(uint32 _value) internal view { + address callAddr = PTR_ADD_INTO_ACTIVE_CALL_ADDRESS; + uint256 cleanupMask = UINT32_MASK; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + _value := and(_value, cleanupMask) + pop(staticcall(_value, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Compiler simulation of the `ptr.shrink` opcode for the virtual `ACTIVE_PTR` pointer. + /// @dev Transforms `ACTIVE_PTR.length` into `ACTIVE_PTR.length - u32(_shrink)`. If underflow happens then it panics. + function ptrShrinkIntoActive(uint32 _shrink) internal view { + address callAddr = PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS; + uint256 cleanupMask = UINT32_MASK; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + _shrink := and(_shrink, cleanupMask) + pop(staticcall(_shrink, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice packs precompile parameters into one word + /// @param _inputMemoryOffset The memory offset in 32-byte words for the input data for calling the precompile. + /// @param _inputMemoryLength The length of the input data in words. + /// @param _outputMemoryOffset The memory offset in 32-byte words for the output data. + /// @param _outputMemoryLength The length of the output data in words. + /// @param _perPrecompileInterpreted The constant, the meaning of which is defined separately for + /// each precompile. For information, please read the documentation of the precompilecall log in + /// the VM. + function packPrecompileParams( + uint32 _inputMemoryOffset, + uint32 _inputMemoryLength, + uint32 _outputMemoryOffset, + uint32 _outputMemoryLength, + uint64 _perPrecompileInterpreted + ) internal pure returns (uint256 rawParams) { + rawParams = _inputMemoryOffset; + rawParams |= uint256(_inputMemoryLength) << 32; + rawParams |= uint256(_outputMemoryOffset) << 64; + rawParams |= uint256(_outputMemoryLength) << 96; + rawParams |= uint256(_perPrecompileInterpreted) << 192; + } + + /// @notice Call precompile with given parameters. + /// @param _rawParams The packed precompile params. They can be retrieved by + /// the `packPrecompileParams` method. + /// @param _gasToBurn The number of gas to burn during this call. + /// @return success Whether the call was successful. + /// @dev The list of currently available precompiles sha256, keccak256, ecrecover. + /// NOTE: The precompile type depends on `this` which calls precompile, which means that only + /// system contracts corresponding to the list of precompiles above can do `precompileCall`. + /// @dev If used not in the `sha256`, `keccak256` or `ecrecover` contracts, it will just burn the gas provided. + /// @dev This method is `unsafe` because it does not check whether there is enough gas to burn. + function unsafePrecompileCall(uint256 _rawParams, uint32 _gasToBurn) internal view returns (bool success) { + address callAddr = PRECOMPILE_CALL_ADDRESS; + + uint256 cleanupMask = UINT32_MASK; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + _gasToBurn := and(_gasToBurn, cleanupMask) + success := staticcall(_rawParams, callAddr, _gasToBurn, 0xFFFF, 0, 0) + } + } + + /// @notice Set `msg.value` to next far call. + /// @param _value The msg.value that will be used for the *next* call. + /// @dev If called not in kernel mode, it will result in a revert (enforced by the VM) + function setValueForNextFarCall(uint128 _value) internal returns (bool success) { + uint256 cleanupMask = UINT128_MASK; + address callAddr = SET_CONTEXT_VALUE_CALL_ADDRESS; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + _value := and(_value, cleanupMask) + success := call(0, callAddr, _value, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Initialize a new event. + /// @param initializer The event initializing value. + /// @param value1 The first topic or data chunk. + function eventInitialize(uint256 initializer, uint256 value1) internal { + address callAddr = EVENT_INITIALIZE_ADDRESS; + assembly { + pop(call(initializer, callAddr, value1, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Continue writing the previously initialized event. + /// @param value1 The first topic or data chunk. + /// @param value2 The second topic or data chunk. + function eventWrite(uint256 value1, uint256 value2) internal { + address callAddr = EVENT_WRITE_ADDRESS; + assembly { + pop(call(value1, callAddr, value2, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Get the packed representation of the `ZkSyncMeta` from the current context. + /// @return meta The packed representation of the ZkSyncMeta. + /// @dev The fields in ZkSyncMeta are NOT tightly packed, i.e. there is a special rule on how + /// they are packed. For more information, please read the documentation on ZkSyncMeta. + function getZkSyncMetaBytes() internal view returns (uint256 meta) { + address callAddr = META_CALL_ADDRESS; + assembly { + meta := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Returns the bits [offset..offset+size-1] of the meta. + /// @param meta Packed representation of the ZkSyncMeta. + /// @param offset The offset of the bits. + /// @param size The size of the extracted number in bits. + /// @return result The extracted number. + function extractNumberFromMeta(uint256 meta, uint256 offset, uint256 size) internal pure returns (uint256 result) { + // Firstly, we delete all the bits after the field + uint256 shifted = (meta << (256 - size - offset)); + // Then we shift everything back + result = (shifted >> (256 - size)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the number of gas + /// that a single byte sent to L1 as pubdata costs. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return gasPerPubdataByte The current price in gas per pubdata byte. + function getGasPerPubdataByteFromMeta(uint256 meta) internal pure returns (uint32 gasPerPubdataByte) { + gasPerPubdataByte = uint32(extractNumberFromMeta(meta, META_GAS_PER_PUBDATA_BYTE_OFFSET, 32)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the number of the current size + /// of the heap in bytes. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return heapSize The size of the memory in bytes byte. + /// @dev The following expression: getHeapSizeFromMeta(getZkSyncMetaBytes()) is + /// equivalent to the MSIZE in Solidity. + function getHeapSizeFromMeta(uint256 meta) internal pure returns (uint32 heapSize) { + heapSize = uint32(extractNumberFromMeta(meta, META_HEAP_SIZE_OFFSET, 32)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the number of the current size + /// of the auxilary heap in bytes. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return auxHeapSize The size of the auxilary memory in bytes byte. + /// @dev You can read more on auxilary memory in the VM1.2 documentation. + function getAuxHeapSizeFromMeta(uint256 meta) internal pure returns (uint32 auxHeapSize) { + auxHeapSize = uint32(extractNumberFromMeta(meta, META_AUX_HEAP_SIZE_OFFSET, 32)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the shardId of `this`. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return shardId The shardId of `this`. + /// @dev Currently only shard 0 (zkRollup) is supported. + function getShardIdFromMeta(uint256 meta) internal pure returns (uint8 shardId) { + shardId = uint8(extractNumberFromMeta(meta, META_SHARD_ID_OFFSET, 8)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the shardId of + /// the msg.sender. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return callerShardId The shardId of the msg.sender. + /// @dev Currently only shard 0 (zkRollup) is supported. + function getCallerShardIdFromMeta(uint256 meta) internal pure returns (uint8 callerShardId) { + callerShardId = uint8(extractNumberFromMeta(meta, META_CALLER_SHARD_ID_OFFSET, 8)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the shardId of + /// the currently executed code. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return codeShardId The shardId of the currently executed code. + /// @dev Currently only shard 0 (zkRollup) is supported. + function getCodeShardIdFromMeta(uint256 meta) internal pure returns (uint8 codeShardId) { + codeShardId = uint8(extractNumberFromMeta(meta, META_CODE_SHARD_ID_OFFSET, 8)); + } + + /// @notice Retrieves the ZkSyncMeta structure. + /// @return meta The ZkSyncMeta execution context parameters. + function getZkSyncMeta() internal view returns (ZkSyncMeta memory meta) { + uint256 metaPacked = getZkSyncMetaBytes(); + meta.gasPerPubdataByte = getGasPerPubdataByteFromMeta(metaPacked); + meta.heapSize = getHeapSizeFromMeta(metaPacked); + meta.auxHeapSize = getAuxHeapSizeFromMeta(metaPacked); + meta.shardId = getShardIdFromMeta(metaPacked); + meta.callerShardId = getCallerShardIdFromMeta(metaPacked); + meta.codeShardId = getCodeShardIdFromMeta(metaPacked); + } + + /// @notice Returns the call flags for the current call. + /// @return callFlags The bitmask of the callflags. + /// @dev Call flags is the value of the first register + /// at the start of the call. + /// @dev The zero bit of the callFlags indicates whether the call is + /// a constructor call. The first bit of the callFlags indicates whether + /// the call is a system one. + function getCallFlags() internal view returns (uint256 callFlags) { + address callAddr = CALLFLAGS_CALL_ADDRESS; + assembly { + callFlags := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Returns the current calldata pointer. + /// @return ptr The current calldata pointer. + /// @dev NOTE: This file is just an integer and it cannot be used + /// to forward the calldata to the next calls in any way. + function getCalldataPtr() internal view returns (uint256 ptr) { + address callAddr = PTR_CALLDATA_CALL_ADDRESS; + assembly { + ptr := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Returns the N-th extraAbiParam for the current call. + /// @return extraAbiData The value of the N-th extraAbiParam for this call. + /// @dev It is equal to the value of the (N+2)-th register + /// at the start of the call. + function getExtraAbiData(uint256 index) internal view returns (uint256 extraAbiData) { + require(index < 10, "There are only 10 accessible registers"); + + address callAddr = GET_EXTRA_ABI_DATA_ADDRESS; + assembly { + extraAbiData := staticcall(index, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Retuns whether the current call is a system call. + /// @return `true` or `false` based on whether the current call is a system call. + function isSystemCall() internal view returns (bool) { + uint256 callFlags = getCallFlags(); + // When the system call is passed, the 2-bit it set to 1 + return (callFlags & 2) != 0; + } + + /// @notice Returns whether the address is a system contract. + /// @param _address The address to test + /// @return `true` or `false` based on whether the `_address` is a system contract. + function isSystemContract(address _address) internal pure returns (bool) { + return uint160(_address) <= uint160(MAX_SYSTEM_CONTRACT_ADDRESS); + } + + /// @notice Method used for burning a certain amount of gas. + /// @param _gasToPay The number of gas to burn. + function burnGas(uint32 _gasToPay) internal view { + bool precompileCallSuccess = unsafePrecompileCall( + 0, // The precompile parameters are formal ones. We only need the precompile call to burn gas. + _gasToPay + ); + require(precompileCallSuccess, "Failed to charge gas"); + } +} diff --git a/system-contracts/contracts/libraries/SystemContractsCaller.sol b/system-contracts/contracts/libraries/SystemContractsCaller.sol new file mode 100644 index 000000000..7be179929 --- /dev/null +++ b/system-contracts/contracts/libraries/SystemContractsCaller.sol @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {MSG_VALUE_SYSTEM_CONTRACT, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT} from "../Constants.sol"; +import "./Utils.sol"; + +// Addresses used for the compiler to be replaced with the +// zkSync-specific opcodes during the compilation. +// IMPORTANT: these are just compile-time constants and are used +// only if used in-place by Yul optimizer. +address constant TO_L1_CALL_ADDRESS = address((1 << 16) - 1); +address constant CODE_ADDRESS_CALL_ADDRESS = address((1 << 16) - 2); +address constant PRECOMPILE_CALL_ADDRESS = address((1 << 16) - 3); +address constant META_CALL_ADDRESS = address((1 << 16) - 4); +address constant MIMIC_CALL_CALL_ADDRESS = address((1 << 16) - 5); +address constant SYSTEM_MIMIC_CALL_CALL_ADDRESS = address((1 << 16) - 6); +address constant MIMIC_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 7); +address constant SYSTEM_MIMIC_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 8); +address constant RAW_FAR_CALL_CALL_ADDRESS = address((1 << 16) - 9); +address constant RAW_FAR_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 10); +address constant SYSTEM_CALL_CALL_ADDRESS = address((1 << 16) - 11); +address constant SYSTEM_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 12); +address constant SET_CONTEXT_VALUE_CALL_ADDRESS = address((1 << 16) - 13); +address constant SET_PUBDATA_PRICE_CALL_ADDRESS = address((1 << 16) - 14); +address constant INCREMENT_TX_COUNTER_CALL_ADDRESS = address((1 << 16) - 15); +address constant PTR_CALLDATA_CALL_ADDRESS = address((1 << 16) - 16); +address constant CALLFLAGS_CALL_ADDRESS = address((1 << 16) - 17); +address constant PTR_RETURNDATA_CALL_ADDRESS = address((1 << 16) - 18); +address constant EVENT_INITIALIZE_ADDRESS = address((1 << 16) - 19); +address constant EVENT_WRITE_ADDRESS = address((1 << 16) - 20); +address constant LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS = address((1 << 16) - 21); +address constant LOAD_LATEST_RETURNDATA_INTO_ACTIVE_PTR_CALL_ADDRESS = address((1 << 16) - 22); +address constant PTR_ADD_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 23); +address constant PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 24); +address constant PTR_PACK_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 25); +address constant MULTIPLICATION_HIGH_ADDRESS = address((1 << 16) - 26); +address constant GET_EXTRA_ABI_DATA_ADDRESS = address((1 << 16) - 27); + +// All the offsets are in bits +uint256 constant META_GAS_PER_PUBDATA_BYTE_OFFSET = 0 * 8; +uint256 constant META_HEAP_SIZE_OFFSET = 8 * 8; +uint256 constant META_AUX_HEAP_SIZE_OFFSET = 12 * 8; +uint256 constant META_SHARD_ID_OFFSET = 28 * 8; +uint256 constant META_CALLER_SHARD_ID_OFFSET = 29 * 8; +uint256 constant META_CODE_SHARD_ID_OFFSET = 30 * 8; + +/// @notice The way to forward the calldata: +/// - Use the current heap (i.e. the same as on EVM). +/// - Use the auxiliary heap. +/// - Forward via a pointer +/// @dev Note, that currently, users do not have access to the auxiliary +/// heap and so the only type of forwarding that will be used by the users +/// are UseHeap and ForwardFatPointer for forwarding a slice of the current calldata +/// to the next call. +enum CalldataForwardingMode { + UseHeap, + ForwardFatPointer, + UseAuxHeap +} + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice A library that allows calling contracts with the `isSystem` flag. + * @dev It is needed to call ContractDeployer and NonceHolder. + */ +library SystemContractsCaller { + /// @notice Makes a call with the `isSystem` flag. + /// @param gasLimit The gas limit for the call. + /// @param to The address to call. + /// @param value The value to pass with the transaction. + /// @param data The calldata. + /// @return success Whether the transaction has been successful. + /// @dev Note, that the `isSystem` flag can only be set when calling system contracts. + function systemCall(uint32 gasLimit, address to, uint256 value, bytes memory data) internal returns (bool success) { + address callAddr = SYSTEM_CALL_CALL_ADDRESS; + + uint32 dataStart; + assembly { + dataStart := add(data, 0x20) + } + uint32 dataLength = uint32(Utils.safeCastToU32(data.length)); + + uint256 farCallAbi = SystemContractsCaller.getFarCallABI( + 0, + 0, + dataStart, + dataLength, + gasLimit, + // Only rollup is supported for now + 0, + CalldataForwardingMode.UseHeap, + false, + true + ); + + if (value == 0) { + // Doing the system call directly + assembly { + success := call(to, callAddr, 0, 0, farCallAbi, 0, 0) + } + } else { + address msgValueSimulator = MSG_VALUE_SYSTEM_CONTRACT; + // We need to supply the mask to the MsgValueSimulator to denote + // that the call should be a system one. + uint256 forwardMask = MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT; + + assembly { + success := call(msgValueSimulator, callAddr, value, to, farCallAbi, forwardMask, 0) + } + } + } + + /// @notice Makes a call with the `isSystem` flag. + /// @param gasLimit The gas limit for the call. + /// @param to The address to call. + /// @param value The value to pass with the transaction. + /// @param data The calldata. + /// @return success Whether the transaction has been successful. + /// @return returnData The returndata of the transaction (revert reason in case the transaction has failed). + /// @dev Note, that the `isSystem` flag can only be set when calling system contracts. + function systemCallWithReturndata( + uint32 gasLimit, + address to, + uint128 value, + bytes memory data + ) internal returns (bool success, bytes memory returnData) { + success = systemCall(gasLimit, to, value, data); + + uint256 size; + assembly { + size := returndatasize() + } + + returnData = new bytes(size); + assembly { + returndatacopy(add(returnData, 0x20), 0, size) + } + } + + /// @notice Makes a call with the `isSystem` flag. + /// @param gasLimit The gas limit for the call. + /// @param to The address to call. + /// @param value The value to pass with the transaction. + /// @param data The calldata. + /// @return returnData The returndata of the transaction. In case the transaction reverts, the error + /// bubbles up to the parent frame. + /// @dev Note, that the `isSystem` flag can only be set when calling system contracts. + function systemCallWithPropagatedRevert( + uint32 gasLimit, + address to, + uint128 value, + bytes memory data + ) internal returns (bytes memory returnData) { + bool success; + (success, returnData) = systemCallWithReturndata(gasLimit, to, value, data); + + if (!success) { + assembly { + let size := mload(returnData) + revert(add(returnData, 0x20), size) + } + } + } + + /// @notice Calculates the packed representation of the FarCallABI. + /// @param dataOffset Calldata offset in memory. Provide 0 unless using custom pointer. + /// @param memoryPage Memory page to use. Provide 0 unless using custom pointer. + /// @param dataStart The start of the calldata slice. Provide the offset in memory + /// if not using custom pointer. + /// @param dataLength The calldata length. Provide the length of the calldata in bytes + /// unless using custom pointer. + /// @param gasPassed The gas to pass with the call. + /// @param shardId Of the account to call. Currently only 0 is supported. + /// @param forwardingMode The forwarding mode to use: + /// - provide CalldataForwardingMode.UseHeap when using your current memory + /// - provide CalldataForwardingMode.ForwardFatPointer when using custom pointer. + /// @param isConstructorCall Whether the call will be a call to the constructor + /// (ignored when the caller is not a system contract). + /// @param isSystemCall Whether the call will have the `isSystem` flag. + /// @return farCallAbi The far call ABI. + /// @dev The `FarCallABI` has the following structure: + /// pub struct FarCallABI { + /// pub memory_quasi_fat_pointer: FatPointer, + /// pub gas_passed: u32, + /// pub shard_id: u8, + /// pub forwarding_mode: FarCallForwardPageType, + /// pub constructor_call: bool, + /// pub to_system: bool, + /// } + /// + /// The FatPointer struct: + /// + /// pub struct FatPointer { + /// pub offset: u32, // offset relative to `start` + /// pub memory_page: u32, // memory page where slice is located + /// pub start: u32, // absolute start of the slice + /// pub length: u32, // length of the slice + /// } + /// + /// @dev Note, that the actual layout is the following: + /// + /// [0..32) bits -- the calldata offset + /// [32..64) bits -- the memory page to use. Can be left blank in most of the cases. + /// [64..96) bits -- the absolute start of the slice + /// [96..128) bits -- the length of the slice. + /// [128..192) bits -- empty bits. + /// [192..224) bits -- gasPassed. + /// [224..232) bits -- forwarding_mode + /// [232..240) bits -- shard id. + /// [240..248) bits -- constructor call flag + /// [248..256] bits -- system call flag + function getFarCallABI( + uint32 dataOffset, + uint32 memoryPage, + uint32 dataStart, + uint32 dataLength, + uint32 gasPassed, + uint8 shardId, + CalldataForwardingMode forwardingMode, + bool isConstructorCall, + bool isSystemCall + ) internal pure returns (uint256 farCallAbi) { + // Fill in the call parameter fields + farCallAbi = getFarCallABIWithEmptyFatPointer( + gasPassed, + shardId, + forwardingMode, + isConstructorCall, + isSystemCall + ); + // Fill in the fat pointer fields + farCallAbi |= dataOffset; + farCallAbi |= (uint256(memoryPage) << 32); + farCallAbi |= (uint256(dataStart) << 64); + farCallAbi |= (uint256(dataLength) << 96); + } + + /// @notice Calculates the packed representation of the FarCallABI with zero fat pointer fields. + /// @param gasPassed The gas to pass with the call. + /// @param shardId Of the account to call. Currently only 0 is supported. + /// @param forwardingMode The forwarding mode to use: + /// - provide CalldataForwardingMode.UseHeap when using your current memory + /// - provide CalldataForwardingMode.ForwardFatPointer when using custom pointer. + /// @param isConstructorCall Whether the call will be a call to the constructor + /// (ignored when the caller is not a system contract). + /// @param isSystemCall Whether the call will have the `isSystem` flag. + /// @return farCallAbiWithEmptyFatPtr The far call ABI with zero fat pointer fields. + function getFarCallABIWithEmptyFatPointer( + uint32 gasPassed, + uint8 shardId, + CalldataForwardingMode forwardingMode, + bool isConstructorCall, + bool isSystemCall + ) internal pure returns (uint256 farCallAbiWithEmptyFatPtr) { + farCallAbiWithEmptyFatPtr |= (uint256(gasPassed) << 192); + farCallAbiWithEmptyFatPtr |= (uint256(forwardingMode) << 224); + farCallAbiWithEmptyFatPtr |= (uint256(shardId) << 232); + if (isConstructorCall) { + farCallAbiWithEmptyFatPtr |= (1 << 240); + } + if (isSystemCall) { + farCallAbiWithEmptyFatPtr |= (1 << 248); + } + } +} diff --git a/system-contracts/contracts/libraries/TransactionHelper.sol b/system-contracts/contracts/libraries/TransactionHelper.sol new file mode 100644 index 000000000..e05781974 --- /dev/null +++ b/system-contracts/contracts/libraries/TransactionHelper.sol @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import "../openzeppelin/token/ERC20/IERC20.sol"; +import "../openzeppelin/token/ERC20/utils/SafeERC20.sol"; + +import "../interfaces/IPaymasterFlow.sol"; +import "../interfaces/IContractDeployer.sol"; +import {ETH_TOKEN_SYSTEM_CONTRACT, BOOTLOADER_FORMAL_ADDRESS} from "../Constants.sol"; +import "./RLPEncoder.sol"; +import "./EfficientCall.sol"; + +/// @dev The type id of zkSync's EIP-712-signed transaction. +uint8 constant EIP_712_TX_TYPE = 0x71; + +/// @dev The type id of legacy transactions. +uint8 constant LEGACY_TX_TYPE = 0x0; +/// @dev The type id of legacy transactions. +uint8 constant EIP_2930_TX_TYPE = 0x01; +/// @dev The type id of EIP1559 transactions. +uint8 constant EIP_1559_TX_TYPE = 0x02; + +/// @notice Structure used to represent zkSync transaction. +struct Transaction { + // The type of the transaction. + uint256 txType; + // The caller. + uint256 from; + // The callee. + uint256 to; + // The gasLimit to pass with the transaction. + // It has the same meaning as Ethereum's gasLimit. + uint256 gasLimit; + // The maximum amount of gas the user is willing to pay for a byte of pubdata. + uint256 gasPerPubdataByteLimit; + // The maximum fee per gas that the user is willing to pay. + // It is akin to EIP1559's maxFeePerGas. + uint256 maxFeePerGas; + // The maximum priority fee per gas that the user is willing to pay. + // It is akin to EIP1559's maxPriorityFeePerGas. + uint256 maxPriorityFeePerGas; + // The transaction's paymaster. If there is no paymaster, it is equal to 0. + uint256 paymaster; + // The nonce of the transaction. + uint256 nonce; + // The value to pass with the transaction. + uint256 value; + // In the future, we might want to add some + // new fields to the struct. The `txData` struct + // is to be passed to account and any changes to its structure + // would mean a breaking change to these accounts. In order to prevent this, + // we should keep some fields as "reserved". + // It is also recommended that their length is fixed, since + // it would allow easier proof integration (in case we will need + // some special circuit for preprocessing transactions). + uint256[4] reserved; + // The transaction's calldata. + bytes data; + // The signature of the transaction. + bytes signature; + // The properly formatted hashes of bytecodes that must be published on L1 + // with the inclusion of this transaction. Note, that a bytecode has been published + // before, the user won't pay fees for its republishing. + bytes32[] factoryDeps; + // The input to the paymaster. + bytes paymasterInput; + // Reserved dynamic type for the future use-case. Using it should be avoided, + // But it is still here, just in case we want to enable some additional functionality. + bytes reservedDynamic; +} + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Library is used to help custom accounts to work with common methods for the Transaction type. + */ +library TransactionHelper { + using SafeERC20 for IERC20; + + /// @notice The EIP-712 typehash for the contract's domain + bytes32 constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId)"); + + bytes32 constant EIP712_TRANSACTION_TYPE_HASH = + keccak256( + "Transaction(uint256 txType,uint256 from,uint256 to,uint256 gasLimit,uint256 gasPerPubdataByteLimit,uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 paymaster,uint256 nonce,uint256 value,bytes data,bytes32[] factoryDeps,bytes paymasterInput)" + ); + + /// @notice Whether the token is Ethereum. + /// @param _addr The address of the token + /// @return `true` or `false` based on whether the token is Ether. + /// @dev This method assumes that address is Ether either if the address is 0 (for convenience) + /// or if the address is the address of the L2EthToken system contract. + function isEthToken(uint256 _addr) internal pure returns (bool) { + return _addr == uint256(uint160(address(ETH_TOKEN_SYSTEM_CONTRACT))) || _addr == 0; + } + + /// @notice Calculate the suggested signed hash of the transaction, + /// i.e. the hash that is signed by EOAs and is recommended to be signed by other accounts. + function encodeHash(Transaction calldata _transaction) internal view returns (bytes32 resultHash) { + if (_transaction.txType == LEGACY_TX_TYPE) { + resultHash = _encodeHashLegacyTransaction(_transaction); + } else if (_transaction.txType == EIP_712_TX_TYPE) { + resultHash = _encodeHashEIP712Transaction(_transaction); + } else if (_transaction.txType == EIP_1559_TX_TYPE) { + resultHash = _encodeHashEIP1559Transaction(_transaction); + } else if (_transaction.txType == EIP_2930_TX_TYPE) { + resultHash = _encodeHashEIP2930Transaction(_transaction); + } else { + // Currently no other transaction types are supported. + // Any new transaction types will be processed in a similar manner. + revert("Encoding unsupported tx"); + } + } + + /// @notice Encode hash of the zkSync native transaction type. + /// @return keccak256 hash of the EIP-712 encoded representation of transaction + function _encodeHashEIP712Transaction(Transaction calldata _transaction) private view returns (bytes32) { + bytes32 structHash = keccak256( + abi.encode( + EIP712_TRANSACTION_TYPE_HASH, + _transaction.txType, + _transaction.from, + _transaction.to, + _transaction.gasLimit, + _transaction.gasPerPubdataByteLimit, + _transaction.maxFeePerGas, + _transaction.maxPriorityFeePerGas, + _transaction.paymaster, + _transaction.nonce, + _transaction.value, + EfficientCall.keccak(_transaction.data), + keccak256(abi.encodePacked(_transaction.factoryDeps)), + EfficientCall.keccak(_transaction.paymasterInput) + ) + ); + + bytes32 domainSeparator = keccak256( + abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256("zkSync"), keccak256("2"), block.chainid) + ); + + return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + } + + /// @notice Encode hash of the legacy transaction type. + /// @return keccak256 of the serialized RLP encoded representation of transaction + function _encodeHashLegacyTransaction(Transaction calldata _transaction) private view returns (bytes32) { + // Hash of legacy transactions are encoded as one of the: + // - RLP(nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0) + // - RLP(nonce, gasPrice, gasLimit, to, value, data) + // + // In this RLP encoding, only the first one above list appears, so we encode each element + // inside list and then concatenate the length of all elements with them. + + bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); + // Encode `gasPrice` and `gasLimit` together to prevent "stack too deep error". + bytes memory encodedGasParam; + { + bytes memory encodedGasPrice = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); + bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); + encodedGasParam = bytes.concat(encodedGasPrice, encodedGasLimit); + } + + bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); + // Encode only the length of the transaction data, and not the data itself, + // so as not to copy to memory a potentially huge transaction data twice. + bytes memory encodedDataLength; + { + // Safe cast, because the length of the transaction data can't be so large. + uint64 txDataLen = uint64(_transaction.data.length); + if (txDataLen != 1) { + // If the length is not equal to one, then only using the length can it be encoded definitely. + encodedDataLength = RLPEncoder.encodeNonSingleBytesLen(txDataLen); + } else if (_transaction.data[0] >= 0x80) { + // If input is a byte in [0x80, 0xff] range, RLP encoding will concatenates 0x81 with the byte. + encodedDataLength = hex"81"; + } + // Otherwise the length is not encoded at all. + } + + // Encode `chainId` according to EIP-155, but only if the `chainId` is specified in the transaction. + bytes memory encodedChainId; + if (_transaction.reserved[0] != 0) { + encodedChainId = bytes.concat(RLPEncoder.encodeUint256(block.chainid), hex"80_80"); + } + + bytes memory encodedListLength; + unchecked { + uint256 listLength = encodedNonce.length + + encodedGasParam.length + + encodedTo.length + + encodedValue.length + + encodedDataLength.length + + _transaction.data.length + + encodedChainId.length; + + // Safe cast, because the length of the list can't be so large. + encodedListLength = RLPEncoder.encodeListLen(uint64(listLength)); + } + + return + keccak256( + bytes.concat( + encodedListLength, + encodedNonce, + encodedGasParam, + encodedTo, + encodedValue, + encodedDataLength, + _transaction.data, + encodedChainId + ) + ); + } + + /// @notice Encode hash of the EIP2930 transaction type. + /// @return keccak256 of the serialized RLP encoded representation of transaction + function _encodeHashEIP2930Transaction(Transaction calldata _transaction) private view returns (bytes32) { + // Hash of EIP2930 transactions is encoded the following way: + // H(0x01 || RLP(chain_id, nonce, gas_price, gas_limit, destination, amount, data, access_list)) + // + // Note, that on zkSync access lists are not supported and should always be empty. + + // Encode all fixed-length params to avoid "stack too deep error" + bytes memory encodedFixedLengthParams; + { + bytes memory encodedChainId = RLPEncoder.encodeUint256(block.chainid); + bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); + bytes memory encodedGasPrice = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); + bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); + bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); + encodedFixedLengthParams = bytes.concat( + encodedChainId, + encodedNonce, + encodedGasPrice, + encodedGasLimit, + encodedTo, + encodedValue + ); + } + + // Encode only the length of the transaction data, and not the data itself, + // so as not to copy to memory a potentially huge transaction data twice. + bytes memory encodedDataLength; + { + // Safe cast, because the length of the transaction data can't be so large. + uint64 txDataLen = uint64(_transaction.data.length); + if (txDataLen != 1) { + // If the length is not equal to one, then only using the length can it be encoded definitely. + encodedDataLength = RLPEncoder.encodeNonSingleBytesLen(txDataLen); + } else if (_transaction.data[0] >= 0x80) { + // If input is a byte in [0x80, 0xff] range, RLP encoding will concatenates 0x81 with the byte. + encodedDataLength = hex"81"; + } + // Otherwise the length is not encoded at all. + } + + // On zkSync, access lists are always zero length (at least for now). + bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); + + bytes memory encodedListLength; + unchecked { + uint256 listLength = encodedFixedLengthParams.length + + encodedDataLength.length + + _transaction.data.length + + encodedAccessListLength.length; + + // Safe cast, because the length of the list can't be so large. + encodedListLength = RLPEncoder.encodeListLen(uint64(listLength)); + } + + return + keccak256( + bytes.concat( + "\x01", + encodedListLength, + encodedFixedLengthParams, + encodedDataLength, + _transaction.data, + encodedAccessListLength + ) + ); + } + + /// @notice Encode hash of the EIP1559 transaction type. + /// @return keccak256 of the serialized RLP encoded representation of transaction + function _encodeHashEIP1559Transaction(Transaction calldata _transaction) private view returns (bytes32) { + // Hash of EIP1559 transactions is encoded the following way: + // H(0x02 || RLP(chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list)) + // + // Note, that on zkSync access lists are not supported and should always be empty. + + // Encode all fixed-length params to avoid "stack too deep error" + bytes memory encodedFixedLengthParams; + { + bytes memory encodedChainId = RLPEncoder.encodeUint256(block.chainid); + bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); + bytes memory encodedMaxPriorityFeePerGas = RLPEncoder.encodeUint256(_transaction.maxPriorityFeePerGas); + bytes memory encodedMaxFeePerGas = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); + bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); + bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); + encodedFixedLengthParams = bytes.concat( + encodedChainId, + encodedNonce, + encodedMaxPriorityFeePerGas, + encodedMaxFeePerGas, + encodedGasLimit, + encodedTo, + encodedValue + ); + } + + // Encode only the length of the transaction data, and not the data itself, + // so as not to copy to memory a potentially huge transaction data twice. + bytes memory encodedDataLength; + { + // Safe cast, because the length of the transaction data can't be so large. + uint64 txDataLen = uint64(_transaction.data.length); + if (txDataLen != 1) { + // If the length is not equal to one, then only using the length can it be encoded definitely. + encodedDataLength = RLPEncoder.encodeNonSingleBytesLen(txDataLen); + } else if (_transaction.data[0] >= 0x80) { + // If input is a byte in [0x80, 0xff] range, RLP encoding will concatenates 0x81 with the byte. + encodedDataLength = hex"81"; + } + // Otherwise the length is not encoded at all. + } + + // On zkSync, access lists are always zero length (at least for now). + bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); + + bytes memory encodedListLength; + unchecked { + uint256 listLength = encodedFixedLengthParams.length + + encodedDataLength.length + + _transaction.data.length + + encodedAccessListLength.length; + + // Safe cast, because the length of the list can't be so large. + encodedListLength = RLPEncoder.encodeListLen(uint64(listLength)); + } + + return + keccak256( + bytes.concat( + "\x02", + encodedListLength, + encodedFixedLengthParams, + encodedDataLength, + _transaction.data, + encodedAccessListLength + ) + ); + } + + /// @notice Processes the common paymaster flows, e.g. setting proper allowance + /// for tokens, etc. For more information on the expected behavior, check out + /// the "Paymaster flows" section in the documentation. + function processPaymasterInput(Transaction calldata _transaction) internal { + require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long"); + + bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]); + if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { + require( + _transaction.paymasterInput.length >= 68, + "The approvalBased paymaster input must be at least 68 bytes long" + ); + + // While the actual data consists of address, uint256 and bytes data, + // the data is needed only for the paymaster, so we ignore it here for the sake of optimization + (address token, uint256 minAllowance) = abi.decode(_transaction.paymasterInput[4:68], (address, uint256)); + address paymaster = address(uint160(_transaction.paymaster)); + + uint256 currentAllowance = IERC20(token).allowance(address(this), paymaster); + if (currentAllowance < minAllowance) { + // Some tokens, e.g. USDT require that the allowance is firsty set to zero + // and only then updated to the new value. + + IERC20(token).safeApprove(paymaster, 0); + IERC20(token).safeApprove(paymaster, minAllowance); + } + } else if (paymasterInputSelector == IPaymasterFlow.general.selector) { + // Do nothing. general(bytes) paymaster flow means that the paymaster must interpret these bytes on his own. + } else { + revert("Unsupported paymaster flow"); + } + } + + /// @notice Pays the required fee for the transaction to the bootloader. + /// @dev Currently it pays the maximum amount "_transaction.maxFeePerGas * _transaction.gasLimit", + /// it will change in the future. + function payToTheBootloader(Transaction calldata _transaction) internal returns (bool success) { + address bootloaderAddr = BOOTLOADER_FORMAL_ADDRESS; + uint256 amount = _transaction.maxFeePerGas * _transaction.gasLimit; + + assembly { + success := call(gas(), bootloaderAddr, amount, 0, 0, 0, 0) + } + } + + // Returns the balance required to process the transaction. + function totalRequiredBalance(Transaction calldata _transaction) internal pure returns (uint256 requiredBalance) { + if (address(uint160(_transaction.paymaster)) != address(0)) { + // Paymaster pays for the fee + requiredBalance = _transaction.value; + } else { + // The user should have enough balance for both the fee and the value of the transaction + requiredBalance = _transaction.maxFeePerGas * _transaction.gasLimit + _transaction.value; + } + } +} diff --git a/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol b/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol new file mode 100644 index 000000000..4ce65f5fb --- /dev/null +++ b/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @dev The library provides a set of functions that help read data from calldata bytes. + * @dev Each of the functions accepts the `bytes calldata` and the offset where data should be read and returns a value of a certain type. + * + * @dev WARNING! + * 1) Functions don't check the length of the bytes array, so it can go out of bounds. + * The user of the library must check for bytes length before using any functions from the library! + * + * 2) Read variables are not cleaned up - https://docs.soliditylang.org/en/v0.8.16/internals/variable_cleanup.html. + * Using data in inline assembly can lead to unexpected behavior! + */ +library UnsafeBytesCalldata { + function readUint16(bytes calldata _bytes, uint256 _start) internal pure returns (uint16 result) { + assembly { + let offset := sub(_bytes.offset, 30) + result := calldataload(add(offset, _start)) + } + } + + function readUint32(bytes calldata _bytes, uint256 _start) internal pure returns (uint32 result) { + assembly { + let offset := sub(_bytes.offset, 28) + result := calldataload(add(offset, _start)) + } + } + + function readUint64(bytes calldata _bytes, uint256 _start) internal pure returns (uint64 result) { + assembly { + let offset := sub(_bytes.offset, 24) + result := calldataload(add(offset, _start)) + } + } + + function readBytes32(bytes calldata _bytes, uint256 _start) internal pure returns (bytes32 result) { + assembly { + result := calldataload(add(_bytes.offset, _start)) + } + } + + function readUint256(bytes calldata _bytes, uint256 _start) internal pure returns (uint256 result) { + assembly { + result := calldataload(add(_bytes.offset, _start)) + } + } +} diff --git a/system-contracts/contracts/libraries/Utils.sol b/system-contracts/contracts/libraries/Utils.sol new file mode 100644 index 000000000..a27915207 --- /dev/null +++ b/system-contracts/contracts/libraries/Utils.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import "./EfficientCall.sol"; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @dev Common utilities used in zkSync system contracts + */ +library Utils { + /// @dev Bit mask of bytecode hash "isConstructor" marker + bytes32 constant IS_CONSTRUCTOR_BYTECODE_HASH_BIT_MASK = + 0x00ff000000000000000000000000000000000000000000000000000000000000; + + /// @dev Bit mask to set the "isConstructor" marker in the bytecode hash + bytes32 constant SET_IS_CONSTRUCTOR_MARKER_BIT_MASK = + 0x0001000000000000000000000000000000000000000000000000000000000000; + + function safeCastToU128(uint256 _x) internal pure returns (uint128) { + require(_x <= type(uint128).max, "Overflow"); + + return uint128(_x); + } + + function safeCastToU32(uint256 _x) internal pure returns (uint32) { + require(_x <= type(uint32).max, "Overflow"); + + return uint32(_x); + } + + function safeCastToU24(uint256 _x) internal pure returns (uint24) { + require(_x <= type(uint24).max, "Overflow"); + + return uint24(_x); + } + + /// @return codeLength The bytecode length in bytes + function bytecodeLenInBytes(bytes32 _bytecodeHash) internal pure returns (uint256 codeLength) { + codeLength = bytecodeLenInWords(_bytecodeHash) << 5; // _bytecodeHash * 32 + } + + /// @return codeLengthInWords The bytecode length in machine words + function bytecodeLenInWords(bytes32 _bytecodeHash) internal pure returns (uint256 codeLengthInWords) { + unchecked { + codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3])); + } + } + + /// @notice Denotes whether bytecode hash corresponds to a contract that already constructed + function isContractConstructed(bytes32 _bytecodeHash) internal pure returns (bool) { + return _bytecodeHash[1] == 0x00; + } + + /// @notice Denotes whether bytecode hash corresponds to a contract that is on constructor or has already been constructed + function isContractConstructing(bytes32 _bytecodeHash) internal pure returns (bool) { + return _bytecodeHash[1] == 0x01; + } + + /// @notice Sets "isConstructor" flag to TRUE for the bytecode hash + /// @param _bytecodeHash The bytecode hash for which it is needed to set the constructing flag + /// @return The bytecode hash with "isConstructor" flag set to TRUE + function constructingBytecodeHash(bytes32 _bytecodeHash) internal pure returns (bytes32) { + // Clear the "isConstructor" marker and set it to 0x01. + return constructedBytecodeHash(_bytecodeHash) | SET_IS_CONSTRUCTOR_MARKER_BIT_MASK; + } + + /// @notice Sets "isConstructor" flag to FALSE for the bytecode hash + /// @param _bytecodeHash The bytecode hash for which it is needed to set the constructing flag + /// @return The bytecode hash with "isConstructor" flag set to FALSE + function constructedBytecodeHash(bytes32 _bytecodeHash) internal pure returns (bytes32) { + return _bytecodeHash & ~IS_CONSTRUCTOR_BYTECODE_HASH_BIT_MASK; + } + + /// @notice Validate the bytecode format and calculate its hash. + /// @param _bytecode The bytecode to hash. + /// @return hashedBytecode The 32-byte hash of the bytecode. + /// Note: The function reverts the execution if the bytecode has non expected format: + /// - Bytecode bytes length is not a multiple of 32 + /// - Bytecode bytes length is not less than 2^21 bytes (2^16 words) + /// - Bytecode words length is not odd + function hashL2Bytecode(bytes calldata _bytecode) internal view returns (bytes32 hashedBytecode) { + // Note that the length of the bytecode must be provided in 32-byte words. + require(_bytecode.length % 32 == 0, "po"); + + uint256 lengthInWords = _bytecode.length / 32; + require(lengthInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words + require(lengthInWords % 2 == 1, "pr"); // bytecode length in words must be odd + hashedBytecode = + EfficientCall.sha(_bytecode) & + 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + // Setting the version of the hash + hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248))); + // Setting the length + hashedBytecode = hashedBytecode | bytes32(lengthInWords << 224); + } +} diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol b/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol new file mode 100644 index 000000000..b816bfed0 --- /dev/null +++ b/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); + + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `from` to `to` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address from, + address to, + uint256 amount + ) external returns (bool); +} diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol b/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol new file mode 100644 index 000000000..bb43e53b6 --- /dev/null +++ b/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + */ +interface IERC20Permit { + /** + * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, + * given ``owner``'s signed approval. + * + * IMPORTANT: The same issues {IERC20-approve} has related to transaction + * ordering also apply here. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `deadline` must be a timestamp in the future. + * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` + * over the EIP712-formatted function arguments. + * - the signature must use ``owner``'s current nonce (see {nonces}). + * + * For more information on the signature format, see the + * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP + * section]. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; + + /** + * @dev Returns the current nonce for `owner`. This value must be + * included whenever a signature is generated for {permit}. + * + * Every successful call to {permit} increases ``owner``'s nonce by one. This + * prevents a signature from being used multiple times. + */ + function nonces(address owner) external view returns (uint256); + + /** + * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol b/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol new file mode 100644 index 000000000..4a07fff2a --- /dev/null +++ b/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) + +pragma solidity ^0.8.0; + +import "../IERC20.sol"; +import "../extensions/IERC20Permit.sol"; +import "../../../utils/Address.sol"; + +/** + * @title SafeERC20 + * @dev Wrappers around ERC20 operations that throw on failure (when the token + * contract returns false). Tokens that return no value (and instead revert or + * throw on failure) are also supported, non-reverting calls are assumed to be + * successful. + * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, + * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. + */ +library SafeERC20 { + using Address for address; + + function safeTransfer( + IERC20 token, + address to, + uint256 value + ) internal { + _callOptionalReturn( + token, + abi.encodeWithSelector(token.transfer.selector, to, value) + ); + } + + function safeTransferFrom( + IERC20 token, + address from, + address to, + uint256 value + ) internal { + _callOptionalReturn( + token, + abi.encodeWithSelector(token.transferFrom.selector, from, to, value) + ); + } + + /** + * @dev Deprecated. This function has issues similar to the ones found in + * {IERC20-approve}, and its usage is discouraged. + * + * Whenever possible, use {safeIncreaseAllowance} and + * {safeDecreaseAllowance} instead. + */ + function safeApprove( + IERC20 token, + address spender, + uint256 value + ) internal { + // safeApprove should only be called when setting an initial allowance, + // or when resetting it to zero. To increase and decrease it, use + // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' + require( + (value == 0) || (token.allowance(address(this), spender) == 0), + "SafeERC20: approve from non-zero to non-zero allowance" + ); + _callOptionalReturn( + token, + abi.encodeWithSelector(token.approve.selector, spender, value) + ); + } + + function safeIncreaseAllowance( + IERC20 token, + address spender, + uint256 value + ) internal { + uint256 newAllowance = token.allowance(address(this), spender) + value; + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.approve.selector, + spender, + newAllowance + ) + ); + } + + function safeDecreaseAllowance( + IERC20 token, + address spender, + uint256 value + ) internal { + unchecked { + uint256 oldAllowance = token.allowance(address(this), spender); + require( + oldAllowance >= value, + "SafeERC20: decreased allowance below zero" + ); + uint256 newAllowance = oldAllowance - value; + _callOptionalReturn( + token, + abi.encodeWithSelector( + token.approve.selector, + spender, + newAllowance + ) + ); + } + } + + function safePermit( + IERC20Permit token, + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) internal { + uint256 nonceBefore = token.nonces(owner); + token.permit(owner, spender, value, deadline, v, r, s); + uint256 nonceAfter = token.nonces(owner); + require( + nonceAfter == nonceBefore + 1, + "SafeERC20: permit did not succeed" + ); + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(IERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that + // the target address contains contract code and also asserts for success in the low-level call. + + bytes memory returndata = address(token).functionCall( + data, + "SafeERC20: low-level call failed" + ); + if (returndata.length > 0) { + // Return data is optional + require( + abi.decode(returndata, (bool)), + "SafeERC20: ERC20 operation did not succeed" + ); + } + } +} diff --git a/system-contracts/contracts/openzeppelin/utils/Address.sol b/system-contracts/contracts/openzeppelin/utils/Address.sol new file mode 100644 index 000000000..7a7d2d5d3 --- /dev/null +++ b/system-contracts/contracts/openzeppelin/utils/Address.sol @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) + +pragma solidity ^0.8.1; + +/** + * @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 + * ==== + * + * [IMPORTANT] + * ==== + * You shouldn't rely on `isContract` to protect against flash loan attacks! + * + * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets + * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract + * constructor. + * ==== + */ + function isContract(address account) internal view returns (bool) { + // This method relies on extcodesize/address.code.length, which returns 0 + // for contracts in construction, since the code is only stored at the end + // of the constructor execution. + + return account.code.length > 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://consensys.net/diligence/blog/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 + functionCallWithValue( + target, + data, + 0, + "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" + ); + (bool success, bytes memory returndata) = target.call{value: value}( + data + ); + return + verifyCallResultFromTarget( + target, + 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) { + (bool success, bytes memory returndata) = target.staticcall(data); + return + verifyCallResultFromTarget( + target, + 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) { + (bool success, bytes memory returndata) = target.delegatecall(data); + return + verifyCallResultFromTarget( + target, + success, + returndata, + errorMessage + ); + } + + /** + * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling + * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. + * + * _Available since v4.8._ + */ + function verifyCallResultFromTarget( + address target, + bool success, + bytes memory returndata, + string memory errorMessage + ) internal view returns (bytes memory) { + if (success) { + if (returndata.length == 0) { + // only check isContract if the call was successful and the return data is empty + // otherwise we already know that it was a contract + require(isContract(target), "Address: call to non-contract"); + } + return returndata; + } else { + _revert(returndata, errorMessage); + } + } + + /** + * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the + * revert reason or 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 { + _revert(returndata, errorMessage); + } + } + + function _revert(bytes memory returndata, string memory errorMessage) + private + pure + { + // 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 + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(errorMessage); + } + } +} diff --git a/system-contracts/contracts/precompiles/EcAdd.yul b/system-contracts/contracts/precompiles/EcAdd.yul new file mode 100644 index 000000000..bfbac645d --- /dev/null +++ b/system-contracts/contracts/precompiles/EcAdd.yul @@ -0,0 +1,441 @@ +object "EcAdd" { + code { + return(0, 0) + } + object "EcAdd_deployed" { + code { + //////////////////////////////////////////////////////////////// + // CONSTANTS + //////////////////////////////////////////////////////////////// + + /// @notice Constant function for value three in Montgomery form. + /// @dev This value was precomputed using Python. + /// @return m_three The value three in Montgomery form. + function MONTGOMERY_THREE() -> m_three { + m_three := 19052624634359457937016868847204597229365286637454337178037183604060995791063 + } + + /// @notice Constant function for the alt_bn128 field order. + /// @dev See https://eips.ethereum.org/EIPS/eip-196 for further details. + /// @return ret The alt_bn128 field order. + function P() -> ret { + ret := 21888242871839275222246405745257275088696311157297823662689037894645226208583 + } + + /// @notice Constant function for the pre-computation of R^2 % N for the Montgomery REDC algorithm. + /// @dev R^2 is the Montgomery residue of the value 2^512. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further detals. + /// @dev This value was precomputed using Python. + /// @return ret The value R^2 modulus the curve field order. + function R2_MOD_P() -> ret { + ret := 3096616502983703923843567936837374451735540968419076528771170197431451843209 + } + + /// @notice Constant function for the pre-computation of N' for the Montgomery REDC algorithm. + /// @dev N' is a value such that NN' = -1 mod R, with N being the curve field order. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further detals. + /// @dev This value was precomputed using Python. + /// @return ret The value N'. + function N_PRIME() -> ret { + ret := 111032442853175714102588374283752698368366046808579839647964533820976443843465 + } + + ////////////////////////////////////////////////////////////////// + // HELPER FUNCTIONS + ////////////////////////////////////////////////////////////////// + + /// @dev Executes the `precompileCall` opcode. + function precompileCall(precompileParams, gasToBurn) -> ret { + // Compiler simulation for calling `precompileCall` opcode + ret := verbatim_2i_1o("precompile", precompileParams, gasToBurn) + } + + /// @notice Burns remaining gas until revert. + /// @dev This function is used to burn gas in the case of a failed precompile call. + function burnGas() { + // Precompiles that do not have a circuit counterpart + // will burn the provided gas by calling this function. + precompileCall(0, gas()) + } + + /// @notice Retrieves the highest half of the multiplication result. + /// @param multiplicand The value to multiply. + /// @param multiplier The multiplier. + /// @return ret The highest half of the multiplication result. + function getHighestHalfOfMultiplication(multiplicand, multiplier) -> ret { + ret := verbatim_2i_1o("mul_high", multiplicand, multiplier) + } + + /// @notice Computes the modular subtraction of two values. + /// @param minuend The value to subtract from. + /// @param subtrahend The value to subtract. + /// @param modulus The modulus. + /// @return difference The modular subtraction of the two values. + function submod(minuend, subtrahend, modulus) -> difference { + difference := addmod(minuend, sub(modulus, subtrahend), modulus) + } + + /// @notice Computes an addition and checks for overflow. + /// @param augend The value to add to. + /// @param addend The value to add. + /// @return sum The sum of the two values. + /// @return overflowed True if the addition overflowed, false otherwise. + function overflowingAdd(augend, addend) -> sum, overflowed { + sum := add(augend, addend) + overflowed := lt(sum, augend) + } + + // @notice Checks if a point is on the curve. + // @dev The curve in question is the alt_bn128 curve. + // @dev The Short Weierstrass equation of the curve is y^2 = x^3 + 3. + // @param x The x coordinate of the point in Montgomery form. + // @param y The y coordinate of the point in Montgomery form. + // @return ret True if the point is on the curve, false otherwise. + function pointIsInCurve(x, y) -> ret { + let ySquared := montgomeryMul(y, y) + let xSquared := montgomeryMul(x, x) + let xQubed := montgomeryMul(xSquared, x) + let xQubedPlusThree := montgomeryAdd(xQubed, MONTGOMERY_THREE()) + + ret := eq(ySquared, xQubedPlusThree) + } + + /// @notice Checks if a point is the point at infinity. + /// @dev The point at infinity is defined as the point (0, 0). + /// @dev See https://eips.ethereum.org/EIPS/eip-196 for further details. + /// @param x The x coordinate of the point. + /// @param y The y coordinate of the point. + /// @return ret True if the point is the point at infinity, false otherwise. + function isInfinity(x, y) -> ret { + ret := iszero(or(x, y)) + } + + /// @notice Checks if a coordinate is on the curve field order. + /// @dev A coordinate is on the curve field order if it is on the range [0, curveFieldOrder). + /// @dev This check is required in the precompile specification. See https://eips.ethereum.org/EIPS/eip-196 for further details. + /// @param coordinate The coordinate to check. + /// @return ret True if the coordinate is in the range, false otherwise. + function isOnFieldOrder(coordinate) -> ret { + ret := lt(coordinate, P()) + } + + /// @notice Computes the inverse in Montgomery Form of a number in Montgomery Form. + /// @dev Reference: https://github.com/lambdaclass/lambdaworks/blob/main/math/src/field/fields/montgomery_backed_prime_fields.rs#L169 + /// @dev Let `base` be a number in Montgomery Form, then base = a*R mod P() being `a` the base number (not in Montgomery Form) + /// @dev Let `inv` be the inverse of a number `a` in Montgomery Form, then inv = a^(-1)*R mod P() + /// @dev The original binary extended euclidean algorithms takes a number a and returns a^(-1) mod N + /// @dev In our case N is P(), and we'd like the input and output to be in Montgomery Form (a*R mod P() + /// @dev and a^(-1)*R mod P() respectively). + /// @dev If we just pass the input as a number in Montgomery Form the result would be a^(-1)*R^(-1) mod P(), + /// @dev but we want it to be a^(-1)*R mod P(). + /// @dev For that, we take advantage of the algorithm's linearity and multiply the result by R^2 mod P() + /// @dev to get R^2*a^(-1)*R^(-1) mod P() = a^(-1)*R mod P() as the desired result in Montgomery Form. + /// @dev `inv` takes the value of `b` or `c` being the result sometimes `b` and sometimes `c`. In paper + /// @dev multiplying `b` or `c` by R^2 mod P() results on starting their values as b = R2_MOD_P() and c = 0. + /// @param base A number `a` in Montgomery Form, then base = a*R mod P(). + /// @return inv The inverse of a number `a` in Montgomery Form, then inv = a^(-1)*R mod P(). + function binaryExtendedEuclideanAlgorithm(base) -> inv { + let modulus := P() + let u := base + let v := modulus + // Avoids unnecessary reduction step. + let b := R2_MOD_P() + let c := 0 + + for {} and(iszero(eq(u, 1)), iszero(eq(v, 1))) {} { + for {} iszero(and(u, 1)) {} { + u := shr(1, u) + let current := b + switch and(current, 1) + case 0 { + b := shr(1, b) + } + case 1 { + b := shr(1, add(b, modulus)) + } + } + + for {} iszero(and(v, 1)) {} { + v := shr(1, v) + let current := c + switch and(current, 1) + case 0 { + c := shr(1, c) + } + case 1 { + c := shr(1, add(c, modulus)) + } + } + + switch gt(v, u) + case 0 { + u := sub(u, v) + if lt(b, c) { + b := add(b, modulus) + } + b := sub(b, c) + } + case 1 { + v := sub(v, u) + if lt(c, b) { + c := add(c, modulus) + } + c := sub(c, b) + } + } + + switch eq(u, 1) + case 0 { + inv := c + } + case 1 { + inv := b + } + } + + /// @notice Implementation of the Montgomery reduction algorithm (a.k.a. REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm + /// @param lowestHalfOfT The lowest half of the value T. + /// @param higherHalfOfT The higher half of the value T. + /// @return S The result of the Montgomery reduction. + function REDC(lowestHalfOfT, higherHalfOfT) -> S { + let m := mul(lowestHalfOfT, N_PRIME()) + let hi := add(higherHalfOfT, getHighestHalfOfMultiplication(m, P())) + let lo, overflowed := overflowingAdd(lowestHalfOfT, mul(m, P())) + if overflowed { + hi := add(hi, 1) + } + S := hi + if iszero(lt(hi, P())) { + S := sub(hi, P()) + } + } + + /// @notice Encodes a field element into the Montgomery form using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on transforming a field element into the Montgomery form. + /// @param a The field element to encode. + /// @return ret The field element in Montgomery form. + function intoMontgomeryForm(a) -> ret { + let hi := getHighestHalfOfMultiplication(a, R2_MOD_P()) + let lo := mul(a, R2_MOD_P()) + ret := REDC(lo, hi) + } + + /// @notice Decodes a field element out of the Montgomery form using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on transforming a field element out of the Montgomery form. + /// @param m The field element in Montgomery form to decode. + /// @return ret The decoded field element. + function outOfMontgomeryForm(m) -> ret { + let hi := 0 + let lo := m + ret := REDC(lo, hi) + } + + /// @notice Computes the Montgomery addition. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param augend The augend in Montgomery form. + /// @param addend The addend in Montgomery form. + /// @return ret The result of the Montgomery addition. + function montgomeryAdd(augend, addend) -> ret { + ret := add(augend, addend) + if iszero(lt(ret, P())) { + ret := sub(ret, P()) + } + } + + /// @notice Computes the Montgomery subtraction. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param minuend The minuend in Montgomery form. + /// @param subtrahend The subtrahend in Montgomery form. + /// @return ret The result of the Montgomery subtraction. + function montgomerySub(minuend, subtrahend) -> ret { + ret := montgomeryAdd(minuend, sub(P(), subtrahend)) + } + + /// @notice Computes the Montgomery multiplication using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param multiplicand The multiplicand in Montgomery form. + /// @param multiplier The multiplier in Montgomery form. + /// @return ret The result of the Montgomery multiplication. + function montgomeryMul(multiplicand, multiplier) -> ret { + let higherHalfOfProduct := getHighestHalfOfMultiplication(multiplicand, multiplier) + let lowestHalfOfProduct := mul(multiplicand, multiplier) + ret := REDC(lowestHalfOfProduct, higherHalfOfProduct) + } + + /// @notice Computes the Montgomery modular inverse skipping the Montgomery reduction step. + /// @dev The Montgomery reduction step is skept because a modification in the binary extended Euclidean algorithm is used to compute the modular inverse. + /// @dev See the function `binaryExtendedEuclideanAlgorithm` for further details. + /// @param a The field element in Montgomery form to compute the modular inverse of. + /// @return invmod The result of the Montgomery modular inverse (in Montgomery form). + function montgomeryModularInverse(a) -> invmod { + invmod := binaryExtendedEuclideanAlgorithm(a) + } + + /// @notice Computes the Montgomery division. + /// @dev The Montgomery division is computed by multiplying the dividend with the modular inverse of the divisor. + /// @param dividend The dividend in Montgomery form. + /// @param divisor The divisor in Montgomery form. + /// @return quotient The result of the Montgomery division. + function montgomeryDiv(dividend, divisor) -> quotient { + quotient := montgomeryMul(dividend, montgomeryModularInverse(divisor)) + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + // Retrieve the coordinates from the calldata + let x1 := calldataload(0) + let y1 := calldataload(32) + let x2 := calldataload(64) + let y2 := calldataload(96) + + let p1IsInfinity := isInfinity(x1, y1) + let p2IsInfinity := isInfinity(x2, y2) + + if and(p1IsInfinity, p2IsInfinity) { + // Infinity + Infinity = Infinity + mstore(0, 0) + mstore(32, 0) + return(0, 64) + } + if and(p1IsInfinity, iszero(p2IsInfinity)) { + // Infinity + P = P + + // Ensure that the coordinates are between 0 and the field order. + if or(iszero(isOnFieldOrder(x2)), iszero(isOnFieldOrder(y2))) { + burnGas() + } + + let m_x2 := intoMontgomeryForm(x2) + let m_y2 := intoMontgomeryForm(y2) + + // Ensure that the point is in the curve (Y^2 = X^3 + 3). + if iszero(pointIsInCurve(m_x2, m_y2)) { + burnGas() + } + + // We just need to go into the Montgomery form to perform the + // computations in pointIsInCurve, but we do not need to come back. + + mstore(0, x2) + mstore(32, y2) + return(0, 64) + } + if and(iszero(p1IsInfinity), p2IsInfinity) { + // P + Infinity = P + + // Ensure that the coordinates are between 0 and the field order. + if or(iszero(isOnFieldOrder(x1)), iszero(isOnFieldOrder(y1))) { + burnGas() + } + + let m_x1 := intoMontgomeryForm(x1) + let m_y1 := intoMontgomeryForm(y1) + + // Ensure that the point is in the curve (Y^2 = X^3 + 3). + if iszero(pointIsInCurve(m_x1, m_y1)) { + burnGas() + } + + // We just need to go into the Montgomery form to perform the + // computations in pointIsInCurve, but we do not need to come back. + + mstore(0, x1) + mstore(32, y1) + return(0, 64) + } + + // Ensure that the coordinates are between 0 and the field order. + if or(iszero(isOnFieldOrder(x1)), iszero(isOnFieldOrder(y1))) { + burnGas() + } + + // Ensure that the coordinates are between 0 and the field order. + if or(iszero(isOnFieldOrder(x2)), iszero(isOnFieldOrder(y2))) { + burnGas() + } + + // There's no need for transforming into Montgomery form + // for this case. + if and(eq(x1, x2), eq(submod(0, y1, P()), y2)) { + // P + (-P) = Infinity + + let m_x1 := intoMontgomeryForm(x1) + let m_y1 := intoMontgomeryForm(y1) + let m_x2 := intoMontgomeryForm(x2) + let m_y2 := intoMontgomeryForm(y2) + + // Ensure that the points are in the curve (Y^2 = X^3 + 3). + if or(iszero(pointIsInCurve(m_x1, m_y1)), iszero(pointIsInCurve(m_x2, m_y2))) { + burnGas() + } + + // We just need to go into the Montgomery form to perform the + // computations in pointIsInCurve, but we do not need to come back. + + mstore(0, 0) + mstore(32, 0) + return(0, 64) + } + + if and(eq(x1, x2), and(iszero(eq(y1, y2)), iszero(eq(y1, submod(0, y2, P()))))) { + burnGas() + } + + if and(eq(x1, x2), eq(y1, y2)) { + // P + P = 2P + + let x := intoMontgomeryForm(x1) + let y := intoMontgomeryForm(y1) + + // Ensure that the points are in the curve (Y^2 = X^3 + 3). + if iszero(pointIsInCurve(x, y)) { + burnGas() + } + + // (3 * x1^2 + a) / (2 * y1) + let x1_squared := montgomeryMul(x, x) + let slope := montgomeryDiv(addmod(x1_squared, addmod(x1_squared, x1_squared, P()), P()), addmod(y, y, P())) + // x3 = slope^2 - 2 * x1 + let x3 := submod(montgomeryMul(slope, slope), addmod(x, x, P()), P()) + // y3 = slope * (x1 - x3) - y1 + let y3 := submod(montgomeryMul(slope, submod(x, x3, P())), y, P()) + + x3 := outOfMontgomeryForm(x3) + y3 := outOfMontgomeryForm(y3) + + mstore(0, x3) + mstore(32, y3) + return(0, 64) + } + + // P1 + P2 = P3 + + x1 := intoMontgomeryForm(x1) + y1 := intoMontgomeryForm(y1) + x2 := intoMontgomeryForm(x2) + y2 := intoMontgomeryForm(y2) + + // Ensure that the points are in the curve (Y^2 = X^3 + 3). + if or(iszero(pointIsInCurve(x1, y1)), iszero(pointIsInCurve(x2, y2))) { + burnGas() + } + + // (y2 - y1) / (x2 - x1) + let slope := montgomeryDiv(submod(y2, y1, P()), submod(x2, x1, P())) + // x3 = slope^2 - x1 - x2 + let x3 := submod(montgomeryMul(slope, slope), addmod(x1, x2, P()), P()) + // y3 = slope * (x1 - x3) - y1 + let y3 := submod(montgomeryMul(slope, submod(x1, x3, P())), y1, P()) + + x3 := outOfMontgomeryForm(x3) + y3 := outOfMontgomeryForm(y3) + + mstore(0, x3) + mstore(32, y3) + return(0, 64) + } + } +} diff --git a/system-contracts/contracts/precompiles/EcMul.yul b/system-contracts/contracts/precompiles/EcMul.yul new file mode 100644 index 000000000..83c45ff09 --- /dev/null +++ b/system-contracts/contracts/precompiles/EcMul.yul @@ -0,0 +1,495 @@ +object "EcMul" { + code { + return(0, 0) + } + object "EcMul_deployed" { + code { + //////////////////////////////////////////////////////////////// + // CONSTANTS + //////////////////////////////////////////////////////////////// + + /// @notice Constant function for value one in Montgomery form. + /// @dev This value was precomputed using Python. + /// @return m_one The value one in Montgomery form. + function MONTGOMERY_ONE() -> m_one { + m_one := 6350874878119819312338956282401532409788428879151445726012394534686998597021 + } + + /// @notice Constant function for value three in Montgomery form. + /// @dev This value was precomputed using Python. + /// @return m_three The value three in Montgomery form. + function MONTGOMERY_THREE() -> m_three { + m_three := 19052624634359457937016868847204597229365286637454337178037183604060995791063 + } + + /// @notice Constant function for value 3*b (i.e. 9) in Montgomery form. + /// @dev This value was precomputed using Python. + /// @return m_b3 The value 9 in Montgomery form. + function MONTGOMERY_B3() -> m_b3 { + m_b3 := 13381388159399823366557795051099241510703237597767364208733475022892534956023 + } + + /// @notice Constant function for the alt_bn128 field order. + /// @dev See https://eips.ethereum.org/EIPS/eip-196 for further details. + /// @return ret The alt_bn128 field order. + function P() -> ret { + ret := 21888242871839275222246405745257275088696311157297823662689037894645226208583 + } + + /// @notice Constant function for the pre-computation of R^2 % N for the Montgomery REDC algorithm. + /// @dev R^2 is the Montgomery residue of the value 2^512. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further detals. + /// @dev This value was precomputed using Python. + /// @return ret The value R^2 modulus the curve field order. + function R2_MOD_P() -> ret { + ret := 3096616502983703923843567936837374451735540968419076528771170197431451843209 + } + + /// @notice Constant function for the pre-computation of N' for the Montgomery REDC algorithm. + /// @dev N' is a value such that NN' = -1 mod R, with N being the curve field order. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further detals. + /// @dev This value was precomputed using Python. + /// @return ret The value N'. + function N_PRIME() -> ret { + ret := 111032442853175714102588374283752698368366046808579839647964533820976443843465 + } + + // //////////////////////////////////////////////////////////////// + // HELPER FUNCTIONS + // //////////////////////////////////////////////////////////////// + + /// @dev Executes the `precompileCall` opcode. + function precompileCall(precompileParams, gasToBurn) -> ret { + // Compiler simulation for calling `precompileCall` opcode + ret := verbatim_2i_1o("precompile", precompileParams, gasToBurn) + } + + /// @notice Burns remaining gas until revert. + /// @dev This function is used to burn gas in the case of a failed precompile call. + function burnGas() { + // Precompiles that do not have a circuit counterpart + // will burn the provided gas by calling this function. + precompileCall(0, gas()) + } + + /// @notice Retrieves the highest half of the multiplication result. + /// @param multiplicand The value to multiply. + /// @param multiplier The multiplier. + /// @return ret The highest half of the multiplication result. + function getHighestHalfOfMultiplication(multiplicand, multiplier) -> ret { + ret := verbatim_2i_1o("mul_high", multiplicand, multiplier) + } + + /// @notice Computes an addition and checks for overflow. + /// @param augend The value to add to. + /// @param addend The value to add. + /// @return sum The sum of the two values. + /// @return overflowed True if the addition overflowed, false otherwise. + function overflowingAdd(augend, addend) -> sum, overflowed { + sum := add(augend, addend) + overflowed := lt(sum, augend) + } + + /// @notice Checks if the LSB of a number is 1. + /// @param x The number to check. + /// @return ret True if the LSB is 1, false otherwise. + function lsbIsOne(x) -> ret { + ret := and(x, 1) + } + + /// @notice Computes the inverse in Montgomery Form of a number in Montgomery Form. + /// @dev Reference: https://github.com/lambdaclass/lambdaworks/blob/main/math/src/field/fields/montgomery_backed_prime_fields.rs#L169 + /// @dev Let `base` be a number in Montgomery Form, then base = a*R mod P() being `a` the base number (not in Montgomery Form) + /// @dev Let `inv` be the inverse of a number `a` in Montgomery Form, then inv = a^(-1)*R mod P() + /// @dev The original binary extended euclidean algorithms takes a number a and returns a^(-1) mod N + /// @dev In our case N is P(), and we'd like the input and output to be in Montgomery Form (a*R mod P() + /// @dev and a^(-1)*R mod P() respectively). + /// @dev If we just pass the input as a number in Montgomery Form the result would be a^(-1)*R^(-1) mod P(), + /// @dev but we want it to be a^(-1)*R mod P(). + /// @dev For that, we take advantage of the algorithm's linearity and multiply the result by R^2 mod P() + /// @dev to get R^2*a^(-1)*R^(-1) mod P() = a^(-1)*R mod P() as the desired result in Montgomery Form. + /// @dev `inv` takes the value of `b` or `c` being the result sometimes `b` and sometimes `c`. In paper + /// @dev multiplying `b` or `c` by R^2 mod P() results on starting their values as b = R2_MOD_P() and c = 0. + /// @param base A number `a` in Montgomery Form, then base = a*R mod P(). + /// @return inv The inverse of a number `a` in Montgomery Form, then inv = a^(-1)*R mod P(). + function binaryExtendedEuclideanAlgorithm(base) -> inv { + let modulus := P() + let u := base + let v := modulus + // Avoids unnecessary reduction step. + let b := R2_MOD_P() + let c := 0 + + for {} and(iszero(eq(u, 1)), iszero(eq(v, 1))) {} { + for {} iszero(and(u, 1)) {} { + u := shr(1, u) + let current := b + switch and(current, 1) + case 0 { + b := shr(1, b) + } + case 1 { + b := shr(1, add(b, modulus)) + } + } + + for {} iszero(and(v, 1)) {} { + v := shr(1, v) + let current := c + switch and(current, 1) + case 0 { + c := shr(1, c) + } + case 1 { + c := shr(1, add(c, modulus)) + } + } + + switch gt(v, u) + case 0 { + u := sub(u, v) + if lt(b, c) { + b := add(b, modulus) + } + b := sub(b, c) + } + case 1 { + v := sub(v, u) + if lt(c, b) { + c := add(c, modulus) + } + c := sub(c, b) + } + } + + switch eq(u, 1) + case 0 { + inv := c + } + case 1 { + inv := b + } + } + + /// @notice Implementation of the Montgomery reduction algorithm (a.k.a. REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_The_REDC_algorithm + /// @param lowestHalfOfT The lowest half of the value T. + /// @param higherHalfOfT The higher half of the value T. + /// @return S The result of the Montgomery reduction. + function REDC(lowestHalfOfT, higherHalfOfT) -> S { + let m := mul(lowestHalfOfT, N_PRIME()) + let hi := add(higherHalfOfT, getHighestHalfOfMultiplication(m, P())) + let lo, overflowed := overflowingAdd(lowestHalfOfT, mul(m, P())) + if overflowed { + hi := add(hi, 1) + } + S := hi + if iszero(lt(hi, P())) { + S := sub(hi, P()) + } + } + + /// @notice Encodes a field element into the Montgomery form using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_The_REDC_algorithm for further details on transforming a field element into the Montgomery form. + /// @param a The field element to encode. + /// @return ret The field element in Montgomery form. + function intoMontgomeryForm(a) -> ret { + let hi := getHighestHalfOfMultiplication(a, R2_MOD_P()) + let lo := mul(a, R2_MOD_P()) + ret := REDC(lo, hi) + } + + /// @notice Decodes a field element out of the Montgomery form using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_The_REDC_algorithm for further details on transforming a field element out of the Montgomery form. + /// @param m The field element in Montgomery form to decode. + /// @return ret The decoded field element. + function outOfMontgomeryForm(m) -> ret { + let hi := 0 + let lo := m + ret := REDC(lo, hi) + } + + /// @notice Computes the Montgomery addition. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param augend The augend in Montgomery form. + /// @param addend The addend in Montgomery form. + /// @return ret The result of the Montgomery addition. + function montgomeryAdd(augend, addend) -> ret { + ret := add(augend, addend) + if iszero(lt(ret, P())) { + ret := sub(ret, P()) + } + } + + /// @notice Computes the Montgomery subtraction. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param minuend The minuend in Montgomery form. + /// @param subtrahend The subtrahend in Montgomery form. + /// @return ret The result of the Montgomery subtraction. + function montgomerySub(minuend, subtrahend) -> ret { + ret := montgomeryAdd(minuend, sub(P(), subtrahend)) + } + + /// @notice Computes the Montgomery multiplication using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param multiplicand The multiplicand in Montgomery form. + /// @param multiplier The multiplier in Montgomery form. + /// @return ret The result of the Montgomery multiplication. + function montgomeryMul(multiplicand, multiplier) -> ret { + let hi := getHighestHalfOfMultiplication(multiplicand, multiplier) + let lo := mul(multiplicand, multiplier) + ret := REDC(lo, hi) + } + + /// @notice Computes the Montgomery modular inverse skipping the Montgomery reduction step. + /// @dev The Montgomery reduction step is skept because a modification in the binary extended Euclidean algorithm is used to compute the modular inverse. + /// @dev See the function `binaryExtendedEuclideanAlgorithm` for further details. + /// @param a The field element in Montgomery form to compute the modular inverse of. + /// @return invmod The result of the Montgomery modular inverse (in Montgomery form). + function montgomeryModularInverse(a) -> invmod { + invmod := binaryExtendedEuclideanAlgorithm(a) + } + + /// @notice Checks if a coordinate is on the curve field order. + /// @dev A coordinate is on the curve field order if it is on the range [0, curveFieldOrder). + /// @param coordinate The coordinate to check. + /// @return ret True if the coordinate is in the range, false otherwise. + function coordinateIsOnFieldOrder(coordinate) -> ret { + ret := lt(coordinate, P()) + } + + /// @notice Checks if affine coordinates are on the curve field order. + /// @dev Affine coordinates are on the curve field order if both coordinates are on the range [0, curveFieldOrder). + /// @param x The x coordinate to check. + /// @param y The y coordinate to check. + /// @return ret True if the coordinates are in the range, false otherwise. + function affinePointCoordinatesAreOnFieldOrder(x, y) -> ret { + ret := and(coordinateIsOnFieldOrder(x), coordinateIsOnFieldOrder(y)) + } + + /// @notice Checks if projective coordinates are on the curve field order. + /// @dev Projective coordinates are on the curve field order if the coordinates are on the range [0, curveFieldOrder) and the z coordinate is not zero. + /// @param x The x coordinate to check. + /// @param y The y coordinate to check. + /// @param z The z coordinate to check. + /// @return ret True if the coordinates are in the range, false otherwise. + function projectivePointCoordinatesAreOnFieldOrder(x, y, z) -> ret { + let _x, _y := projectiveIntoAffine(x, y, z) + ret := and(z, affinePointCoordinatesAreOnFieldOrder(_x, _y)) + } + + // @notice Checks if a point in affine coordinates in Montgomery form is on the curve. + // @dev The curve in question is the alt_bn128 curve. + // @dev The Short Weierstrass equation of the curve is y^2 = x^3 + 3. + // @param x The x coordinate of the point in Montgomery form. + // @param y The y coordinate of the point in Montgomery form. + // @return ret True if the point is on the curve, false otherwise. + function affinePointIsOnCurve(x, y) -> ret { + let ySquared := montgomeryMul(y, y) + let xSquared := montgomeryMul(x, x) + let xQubed := montgomeryMul(xSquared, x) + let xQubedPlusThree := montgomeryAdd(xQubed, MONTGOMERY_THREE()) + + ret := eq(ySquared, xQubedPlusThree) + } + + /// @notice Checks if a point in affine coordinates is the point at infinity. + /// @dev The point at infinity is defined as the point (0, 0). + /// @dev See https://eips.ethereum.org/EIPS/eip-196 for further details. + /// @param x The x coordinate of the point in Montgomery form. + /// @param y The y coordinate of the point in Montgomery form. + /// @return ret True if the point is the point at infinity, false otherwise. + function affinePointIsInfinity(x, y) -> ret { + ret := and(iszero(x), iszero(y)) + } + + /// @notice Checks if a point in projective coordinates in Montgomery form is the point at infinity. + /// @dev The point at infinity is defined as the point (0, 0, 0). + /// @param x The x coordinate of the point in Montgomery form. + /// @param y The y coordinate of the point in Montgomery form. + /// @param z The z coordinate of the point in Montgomery form. + /// @return ret True if the point is the point at infinity, false otherwise. + function projectivePointIsInfinity(x, y, z) -> ret { + ret := iszero(z) + } + + /// @notice Converts a point in affine coordinates to projective coordinates in Montgomery form. + /// @dev The point at infinity is defined as the point (0, 0, 0). + /// @dev For performance reasons, the point is assumed to be previously checked to be on the + /// @dev curve and not the point at infinity. + /// @param xp The x coordinate of the point P in affine coordinates in Montgomery form. + /// @param yp The y coordinate of the point P in affine coordinates in Montgomery form. + /// @return xr The x coordinate of the point P in projective coordinates in Montgomery form. + /// @return yr The y coordinate of the point P in projective coordinates in Montgomery form. + /// @return zr The z coordinate of the point P in projective coordinates in Montgomery form. + function projectiveFromAffine(xp, yp) -> xr, yr, zr { + xr := xp + yr := yp + zr := MONTGOMERY_ONE() + } + + /// @notice Converts a point in projective coordinates to affine coordinates in Montgomery form. + /// @dev See https://www.nayuki.io/page/elliptic-curve-point-addition-in-projective-coordinates for further details. + /// @dev Reverts if the point is not on the curve. + /// @param xp The x coordinate of the point P in projective coordinates in Montgomery form. + /// @param yp The y coordinate of the point P in projective coordinates in Montgomery form. + /// @param zp The z coordinate of the point P in projective coordinates in Montgomery form. + /// @return xr The x coordinate of the point P in affine coordinates in Montgomery form. + /// @return yr The y coordinate of the point P in affine coordinates in Montgomery form. + function projectiveIntoAffine(xp, yp, zp) -> xr, yr { + if zp { + let zp_inv := montgomeryModularInverse(zp) + xr := montgomeryMul(xp, zp_inv) + yr := montgomeryMul(yp, zp_inv) + } + } + + /// @notice Doubles a point in projective coordinates in Montgomery form. + /// @dev See Algorithm 9 in https://eprint.iacr.org/2015/1060.pdf for further details. + /// @dev The point is assumed to be on the curve. + /// @dev It works correctly for the point at infinity. + /// @param xp The x coordinate of the point P in projective coordinates in Montgomery form. + /// @param yp The y coordinate of the point P in projective coordinates in Montgomery form. + /// @param zp The z coordinate of the point P in projective coordinates in Montgomery form. + /// @return xr The x coordinate of the point 2P in projective coordinates in Montgomery form. + /// @return yr The y coordinate of the point 2P in projective coordinates in Montgomery form. + /// @return zr The z coordinate of the point 2P in projective coordinates in Montgomery form. + function projectiveDouble(xp, yp, zp) -> xr, yr, zr { + let t0 := montgomeryMul(yp, yp) + zr := montgomeryAdd(t0, t0) + zr := montgomeryAdd(zr, zr) + zr := montgomeryAdd(zr, zr) + let t1 := montgomeryMul(yp, zp) + let t2 := montgomeryMul(zp, zp) + t2 := montgomeryMul(MONTGOMERY_B3(), t2) + xr := montgomeryMul(t2, zr) + yr := montgomeryAdd(t0, t2) + zr := montgomeryMul(t1, zr) + t1 := montgomeryAdd(t2, t2) + t2 := montgomeryAdd(t1, t2) + t0 := montgomerySub(t0, t2) + yr := montgomeryMul(t0, yr) + yr := montgomeryAdd(xr, yr) + t1 := montgomeryMul(xp, yp) + xr := montgomeryMul(t0, t1) + xr := montgomeryAdd(xr, xr) + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + // Retrieve the coordinates from the calldata + let x := calldataload(0) + let y := calldataload(32) + if iszero(affinePointCoordinatesAreOnFieldOrder(x, y)) { + burnGas() + } + let scalar := calldataload(64) + + if affinePointIsInfinity(x, y) { + // Infinity * scalar = Infinity + return(0x00, 0x40) + } + + let m_x := intoMontgomeryForm(x) + let m_y := intoMontgomeryForm(y) + + // Ensure that the point is in the curve (Y^2 = X^3 + 3). + if iszero(affinePointIsOnCurve(m_x, m_y)) { + burnGas() + } + + if eq(scalar, 0) { + // P * 0 = Infinity + return(0x00, 0x40) + } + if eq(scalar, 1) { + // P * 1 = P + mstore(0x00, x) + mstore(0x20, y) + return(0x00, 0x40) + } + + let xp, yp, zp := projectiveFromAffine(m_x, m_y) + + if eq(scalar, 2) { + let xr, yr, zr := projectiveDouble(xp, yp, zp) + + xr, yr := projectiveIntoAffine(xr, yr, zr) + xr := outOfMontgomeryForm(xr) + yr := outOfMontgomeryForm(yr) + + mstore(0x00, xr) + mstore(0x20, yr) + return(0x00, 0x40) + } + + let xq := xp + let yq := yp + let zq := zp + let xr := 0 + let yr := MONTGOMERY_ONE() + let zr := 0 + for {} scalar {} { + if lsbIsOne(scalar) { + let rIsInfinity := projectivePointIsInfinity(xr, yr, zr) + + if rIsInfinity { + // Infinity + P = P + xr := xq + yr := yq + zr := zq + + xq, yq, zq := projectiveDouble(xq, yq, zq) + // Check next bit + scalar := shr(1, scalar) + continue + } + + let t0 := montgomeryMul(yq, zr) + let t1 := montgomeryMul(yr, zq) + let t := montgomerySub(t0, t1) + let u0 := montgomeryMul(xq, zr) + let u1 := montgomeryMul(xr, zq) + let u := montgomerySub(u0, u1) + + // t = (yq*zr - yr*zq); u = (xq*zr - xr*zq) + if iszero(or(t, u)) { + // P + P = 2P + xr, yr, zr := projectiveDouble(xr, yr, zr) + + xq := xr + yq := yr + zq := zr + // Check next bit + scalar := shr(1, scalar) + continue + } + + // P1 + P2 = P3 + let u2 := montgomeryMul(u, u) + let u3 := montgomeryMul(u2, u) + let v := montgomeryMul(zq, zr) + let w := montgomerySub(montgomeryMul(montgomeryMul(t, t), v), montgomeryMul(u2, montgomeryAdd(u0, u1))) + + xr := montgomeryMul(u, w) + yr := montgomerySub(montgomeryMul(t, montgomerySub(montgomeryMul(u0, u2), w)), montgomeryMul(t0, u3)) + zr := montgomeryMul(u3, v) + } + + xq, yq, zq := projectiveDouble(xq, yq, zq) + // Check next bit + scalar := shr(1, scalar) + } + + xr, yr := projectiveIntoAffine(xr, yr, zr) + xr := outOfMontgomeryForm(xr) + yr := outOfMontgomeryForm(yr) + + mstore(0, xr) + mstore(32, yr) + return(0, 64) + } + } +} diff --git a/system-contracts/contracts/precompiles/Ecrecover.yul b/system-contracts/contracts/precompiles/Ecrecover.yul new file mode 100644 index 000000000..cbb8fcc0f --- /dev/null +++ b/system-contracts/contracts/precompiles/Ecrecover.yul @@ -0,0 +1,100 @@ +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The contract used to emulate EVM's ecrecover precompile. + * @dev It uses `precompileCall` to call the zkEVM built-in precompiles. + */ +object "Ecrecover" { + code { + return(0, 0) + } + object "Ecrecover_deployed" { + code { + //////////////////////////////////////////////////////////////// + // CONSTANTS + //////////////////////////////////////////////////////////////// + + // Group order of secp256k1, see https://en.bitcoin.it/wiki/Secp256k1 + function SECP256K1_GROUP_SIZE() -> ret { + ret := 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 + } + + /// @dev The gas cost of processing ecrecover circuit precompile. + function ECRECOVER_GAS_COST() -> ret { + ret := 7000 + } + + //////////////////////////////////////////////////////////////// + // HELPER FUNCTIONS + //////////////////////////////////////////////////////////////// + + // @dev Packs precompile parameters into one word. + // Note: functions expect to work with 32/64 bits unsigned integers. + // Caller should ensure the type matching before! + function unsafePackPrecompileParams( + uint32_inputOffsetInWords, + uint32_inputLengthInWords, + uint32_outputOffsetInWords, + uint32_outputLengthInWords, + uint64_perPrecompileInterpreted + ) -> rawParams { + rawParams := uint32_inputOffsetInWords + rawParams := or(rawParams, shl(32, uint32_inputLengthInWords)) + rawParams := or(rawParams, shl(64, uint32_outputOffsetInWords)) + rawParams := or(rawParams, shl(96, uint32_outputLengthInWords)) + rawParams := or(rawParams, shl(192, uint64_perPrecompileInterpreted)) + } + + /// @dev Executes the `precompileCall` opcode. + function precompileCall(precompileParams, gasToBurn) -> ret { + // Compiler simulation for calling `precompileCall` opcode + ret := verbatim_2i_1o("precompile", precompileParams, gasToBurn) + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + let digest := calldataload(0) + let v := calldataload(32) + let r := calldataload(64) + let s := calldataload(96) + + // Validate the input by the yellow paper rules (Appendix E. Precompiled contracts) + let vIsInvalid := iszero(or(eq(v, 27), eq(v, 28))) + let sIsInvalid := or(eq(s, 0), gt(s, sub(SECP256K1_GROUP_SIZE(), 1))) + let rIsInvalid := or(eq(r, 0), gt(r, sub(SECP256K1_GROUP_SIZE(), 1))) + + if or(vIsInvalid, or(sIsInvalid, rIsInvalid)) { + return(0, 0) + } + + // Store the data in memory, so the ecrecover circuit will read it + mstore(0, digest) + mstore(32, sub(v, 27)) + mstore(64, r) + mstore(96, s) + + let precompileParams := unsafePackPrecompileParams( + 0, // input offset in words + 4, // input length in words (the signed digest, v, r, s) + 0, // output offset in words + 2, // output length in words (success, signer) + 0 // No special meaning, ecrecover circuit doesn't check this value + ) + let gasToPay := ECRECOVER_GAS_COST() + + // Check whether the call is successfully handled by the ecrecover circuit + let success := precompileCall(precompileParams, gasToPay) + let internalSuccess := mload(0) + + switch and(success, internalSuccess) + case 0 { + return(0, 0) + } + default { + return(32, 32) + } + } + } +} diff --git a/system-contracts/contracts/precompiles/Keccak256.yul b/system-contracts/contracts/precompiles/Keccak256.yul new file mode 100644 index 000000000..b078d5807 --- /dev/null +++ b/system-contracts/contracts/precompiles/Keccak256.yul @@ -0,0 +1,128 @@ +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The contract used to emulate EVM's keccak256 opcode. + * @dev It accepts the data to be hashed, pad it by the specification + * and uses `precompileCall` to call the zkEVM built-in precompiles. + * @dev Thus keccak256 precompile circuit operates over padded data to perform efficient sponge round computation. + */ +object "Keccak256" { + code { + return(0, 0) + } + object "Keccak256_deployed" { + code { + //////////////////////////////////////////////////////////////// + // CONSTANTS + //////////////////////////////////////////////////////////////// + + /// @dev The size of the processing keccak256 block in bytes. + function BLOCK_SIZE() -> ret { + ret := 136 + } + + /// @dev The gas cost of processing one keccak256 round. + function KECCAK_ROUND_GAS_COST() -> ret { + ret := 40 + } + + //////////////////////////////////////////////////////////////// + // HELPER FUNCTIONS + //////////////////////////////////////////////////////////////// + + // @dev Packs precompile parameters into one word. + // Note: functions expect to work with 32/64 bits unsigned integers. + // Caller should ensure the type matching before! + function unsafePackPrecompileParams( + uint32_inputOffsetInWords, + uint32_inputLengthInWords, + uint32_outputOffsetInWords, + uint32_outputLengthInWords, + uint64_perPrecompileInterpreted + ) -> rawParams { + rawParams := uint32_inputOffsetInWords + rawParams := or(rawParams, shl(32, uint32_inputLengthInWords)) + rawParams := or(rawParams, shl(64, uint32_outputOffsetInWords)) + rawParams := or(rawParams, shl(96, uint32_outputLengthInWords)) + rawParams := or(rawParams, shl(192, uint64_perPrecompileInterpreted)) + } + + /// @dev Executes the `precompileCall` opcode. + function precompileCall(precompileParams, gasToBurn) -> ret { + // Compiler simulation for calling `precompileCall` opcode + ret := verbatim_2i_1o("precompile", precompileParams, gasToBurn) + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + // Copy calldata to memory for pad it + let bytesSize := calldatasize() + calldatacopy(0, 0, bytesSize) + + let precompileParams + let gasToPay + + // Most often keccak256 is called with "short" input, so optimize it as a special case. + // NOTE: we consider the special case for sizes less than `BLOCK_SIZE() - 1`, so + // there is only one round and it is and padding can be done branchless + switch lt(bytesSize, sub(BLOCK_SIZE(), 1)) + case true { + // Write the 0x01 after the payload bytes and 0x80 at last byte of padded bytes + mstore(bytesSize, 0x0100000000000000000000000000000000000000000000000000000000000000) + mstore( + sub(BLOCK_SIZE(), 1), + 0x8000000000000000000000000000000000000000000000000000000000000000 + ) + + precompileParams := unsafePackPrecompileParams( + 0, // input offset in words + 5, // input length in words (Math.ceil(136/32) = 5) + 0, // output offset in words + 1, // output length in words + 1 // number of rounds + ) + gasToPay := KECCAK_ROUND_GAS_COST() + } + default { + let padLen := sub(BLOCK_SIZE(), mod(bytesSize, BLOCK_SIZE())) + let paddedByteSize := add(bytesSize, padLen) + + switch eq(padLen, 1) + case true { + // Write 0x81 after the payload bytes + mstore(bytesSize, 0x8100000000000000000000000000000000000000000000000000000000000000) + } + default { + // Write the 0x01 after the payload bytes and 0x80 at last byte of padded bytes + mstore(bytesSize, 0x0100000000000000000000000000000000000000000000000000000000000000) + mstore( + sub(paddedByteSize, 1), + 0x8000000000000000000000000000000000000000000000000000000000000000 + ) + } + + let numRounds := div(paddedByteSize, BLOCK_SIZE()) + precompileParams := unsafePackPrecompileParams( + 0, // input offset in words + div(add(paddedByteSize, 31), 32), // input length in words (safe to pass, never exceed `type(uint32).max`) + 0, // output offset in words + 1, // output length in words + numRounds // number of rounds (safe to pass, never exceed `type(uint64).max`) + ) + gasToPay := mul(KECCAK_ROUND_GAS_COST(), numRounds) + } + + let success := precompileCall(precompileParams, gasToPay) + + switch success + case 0 { + revert(0, 0) + } + default { + return(0, 32) + } + } + } +} diff --git a/system-contracts/contracts/precompiles/SHA256.yul b/system-contracts/contracts/precompiles/SHA256.yul new file mode 100644 index 000000000..fba02d5ef --- /dev/null +++ b/system-contracts/contracts/precompiles/SHA256.yul @@ -0,0 +1,103 @@ +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The contract used to emulate EVM's sha256 precompile. + * @dev It accepts the data to be hashed, pad it by the specification + * and uses `precompileCall` to call the zkEVM built-in precompiles. + * @dev Thus sha256 precompile circuit operates over padded data to perform efficient sponge round computation. + */ +object "SHA256" { + code { + return(0, 0) + } + object "SHA256_deployed" { + code { + //////////////////////////////////////////////////////////////// + // CONSTANTS + //////////////////////////////////////////////////////////////// + + /// @dev The size of the processing sha256 block in bytes. + function BLOCK_SIZE() -> ret { + ret := 64 + } + + /// @dev The gas cost of processing one sha256 round. + function SHA256_ROUND_GAS_COST() -> ret { + ret := 7 + } + + //////////////////////////////////////////////////////////////// + // HELPER FUNCTIONS + //////////////////////////////////////////////////////////////// + + // @dev Packs precompile parameters into one word. + // Note: functions expect to work with 32/64 bits unsigned integers. + // Caller should ensure the type matching before! + function unsafePackPrecompileParams( + uint32_inputOffsetInWords, + uint32_inputLengthInWords, + uint32_outputOffsetInWords, + uint32_outputLengthInWords, + uint64_perPrecompileInterpreted + ) -> rawParams { + rawParams := uint32_inputOffsetInWords + rawParams := or(rawParams, shl(32, uint32_inputLengthInWords)) + rawParams := or(rawParams, shl(64, uint32_outputOffsetInWords)) + rawParams := or(rawParams, shl(96, uint32_outputLengthInWords)) + rawParams := or(rawParams, shl(192, uint64_perPrecompileInterpreted)) + } + + /// @dev Executes the `precompileCall` opcode. + function precompileCall(precompileParams, gasToBurn) -> ret { + // Compiler simulation for calling `precompileCall` opcode + ret := verbatim_2i_1o("precompile", precompileParams, gasToBurn) + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + // Copy calldata to memory for pad it + let bytesSize := calldatasize() + calldatacopy(0, 0, bytesSize) + + // The sha256 padding includes additional 8 bytes of the total message's length in bits, + // so calculate the "full" message length with it. + let extendBytesLen := add(bytesSize, 8) + + let padLen := sub(BLOCK_SIZE(), mod(extendBytesLen, BLOCK_SIZE())) + let paddedBytesSize := add(extendBytesLen, padLen) + + // The original message size in bits + let binSize := mul(bytesSize, 8) + // Same bin size, but shifted to the left, needed for the padding + let leftShiftedBinSize := shl(sub(256, 64), binSize) + + // Write 0x80000... as padding according the sha256 specification + mstore(bytesSize, 0x8000000000000000000000000000000000000000000000000000000000000000) + // then will be some zeroes and BE encoded bit length + mstore(sub(paddedBytesSize, 8), leftShiftedBinSize) + + let numRounds := div(paddedBytesSize, BLOCK_SIZE()) + let precompileParams := unsafePackPrecompileParams( + 0, // input offset in words + // Always divisable by 32, since `BLOCK_SIZE()` is 64 bytes + div(paddedBytesSize, 32), // input length in words (safe to pass, never exceed `type(uint32).max`) + 0, // output offset in words + 1, // output length in words + numRounds // number of rounds (safe to pass, never exceed `type(uint64).max`) + ) + let gasToPay := mul(SHA256_ROUND_GAS_COST(), numRounds) + + let success := precompileCall(precompileParams, gasToPay) + + switch success + case 0 { + revert(0, 0) + } + default { + return(0, 32) + } + } + } +} diff --git a/system-contracts/contracts/test-contracts/DelegateCaller.sol b/system-contracts/contracts/test-contracts/DelegateCaller.sol new file mode 100644 index 000000000..caa5aae6b --- /dev/null +++ b/system-contracts/contracts/test-contracts/DelegateCaller.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +contract DelegateCaller { + function delegateCall(address _to) external payable { + assembly { + calldatacopy(0, 0, calldatasize()) + let result := delegatecall(gas(), _to, 0, calldatasize(), 0, 0) + returndatacopy(0, 0, returndatasize()) + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/system-contracts/contracts/test-contracts/Deployable.sol b/system-contracts/contracts/test-contracts/Deployable.sol new file mode 100644 index 000000000..be35861a4 --- /dev/null +++ b/system-contracts/contracts/test-contracts/Deployable.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +contract Deployable { + event Deployed(uint256 value, bytes data); + + constructor() payable { + uint256 len; + assembly { + len := codesize() + } + bytes memory data = new bytes(len); + assembly { + codecopy(add(data, 0x20), 0, len) + } + emit Deployed(msg.value, data); + } +} diff --git a/system-contracts/contracts/test-contracts/ExtraAbiCaller.zasm b/system-contracts/contracts/test-contracts/ExtraAbiCaller.zasm new file mode 100644 index 000000000..04343af3f --- /dev/null +++ b/system-contracts/contracts/test-contracts/ExtraAbiCaller.zasm @@ -0,0 +1,60 @@ +.text + .file "main" + .globl __entry +__entry: +.func_begin0: + sub.s! 0, r2, r0 + jump.eq @.RUNTIME_CODE + ; deployment code + add 32, r0, r1 + st.1 r0, r1 + st.1 r1, r0 + add @CPI0_1[0], r0, r1 + ret.ok.to_label r1, @DEFAULT_FAR_RETURN +.RUNTIME_CODE: + ; ABI: + ; 0-32 address(in the lowest 20 bytes) + ; 32-64 msg.value + ; 64-384 extra data + ; 384+ calldata + ; + ; load address into r2 + ld.inc r1, r2, r1 + ; set msg.value + ld.inc r1, r3, r1 + context.set_context_u128 r3 + ; load extra abi data into r3-r12 + ld.inc r1, r3, r1 + ld.inc r1, r4, r1 + ld.inc r1, r5, r1 + ld.inc r1, r6, r1 + ld.inc r1, r7, r1 + ld.inc r1, r8, r1 + ld.inc r1, r9, r1 + ld.inc r1, r10, r1 + ld.inc r1, r11, r1 + ld.inc r1, r12, r1 + ptr.pack.s @CPI0_0[0], r1, r1 + far_call r1, r2, @.CALL_REVERT + ptr.pack.s @CPI0_2[0], r1, r1 + ret.ok r1 +.CALL_REVERT: + ptr.pack.s @CPI0_2[0], r1, r1 + ret.revert r1 +.func_end0: + .note.GNU-stack + .rodata +; far call abi: +; gas amount = 0xFFFFFFFF(max) +; forwarding mode = fat ptr +; shard id = 0 +; constructor flag = false +; system call flag = true +; 01 00 00 01 FFFFFFFF 0000000000000000 00000000000000000000000000000000 +CPI0_0: + .cell 452312902503159716397502014137536550255307801666780882257920705274096648192 +CPI0_1: + .cell 5070602400912917605986812821504 +; 01 0000000000000000 00000000000000000000000000000000 +CPI0_2: + .cell 6277101735386680763835789423207666416102355444464034512896 diff --git a/system-contracts/contracts/test-contracts/MockContract.sol b/system-contracts/contracts/test-contracts/MockContract.sol new file mode 100644 index 000000000..1505be34c --- /dev/null +++ b/system-contracts/contracts/test-contracts/MockContract.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +contract MockContract { + event Called(uint256 value, bytes data); + + struct CallResult { + bytes input; + bool failure; + bytes returnData; + } + + CallResult[] private results; + + constructor() { + // Clean results if mock was redeployed. + delete results; + } + + // This function call will not pass to fallback, but this is fine for the tests. + function setResult(CallResult calldata result) external { + bytes32 inputKeccak = keccak256(result.input); + for (uint256 i = 0; i < results.length; i++) { + if (keccak256(results[i].input) == inputKeccak) { + results[i] = result; + return; + } + } + results.push(result); + } + + fallback() external payable { + bytes memory data = msg.data; + bytes32 inputKeccak = keccak256(data); + + // empty return data with successful result by default. + bool failure; + bytes memory returnData; + + for (uint256 i = 0; i < results.length; i++) { + if (keccak256(results[i].input) == inputKeccak) { + failure = results[i].failure; + returnData = results[i].returnData; + break; + } + } + + // Emitting event only if empty successful result expected. + // Can fail if call context is static, but usually it's not a case, + // because view/pure call without return data doesn't make sense. + // Useful, because for such calls we can check for this event, + // to be sure that the needed call was made. + if (!failure && returnData.length == 0) { + emit Called(msg.value, data); + } + + assembly { + switch failure + case 0 { + return(add(returnData, 0x20), mload(returnData)) + } + default { + revert(add(returnData, 0x20), mload(returnData)) + } + } + } +} diff --git a/system-contracts/contracts/test-contracts/SystemCaller.sol b/system-contracts/contracts/test-contracts/SystemCaller.sol new file mode 100644 index 000000000..77bfa707f --- /dev/null +++ b/system-contracts/contracts/test-contracts/SystemCaller.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {SYSTEM_CALL_CALL_ADDRESS, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, SystemContractsCaller, CalldataForwardingMode} from "../libraries/SystemContractsCaller.sol"; +import "../libraries/Utils.sol"; + +address constant REAL_MSG_VALUE_SYSTEM_CONTRACT = address(0x8009); + +// Proxy that sets system call, does the same thing as `ExtraAbiCaller.zasm`, but can be called with callee abi, which is more convenient. +// Also updates the real balance of the callee. +contract SystemCaller { + address immutable to; + + constructor(address _to) { + to = _to; + } + + // The library method will not work, because it uses the MsgValueSimulator test address. + fallback() external payable { + address callAddr = SYSTEM_CALL_CALL_ADDRESS; + + address _to = to; + bytes memory data = msg.data; + uint32 dataStart; + assembly { + dataStart := add(data, 0x20) + } + uint32 dataLength = uint32(Utils.safeCastToU32(data.length)); + + uint256 farCallAbi = SystemContractsCaller.getFarCallABI( + 0, + 0, + dataStart, + dataLength, + Utils.safeCastToU32(gasleft()), + // Only rollup is supported for now + 0, + CalldataForwardingMode.UseHeap, + false, + true + ); + + bool success; + if (msg.value == 0) { + // Doing the system call directly + assembly { + success := call(_to, callAddr, 0, 0, farCallAbi, 0, 0) + } + } else { + address msgValueSimulator = REAL_MSG_VALUE_SYSTEM_CONTRACT; + // We need to supply the mask to the MsgValueSimulator to denote + // that the call should be a system one. + uint256 forwardMask = MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT; + + assembly { + success := call(msgValueSimulator, callAddr, callvalue(), _to, farCallAbi, forwardMask, 0) + } + } + uint256 returnDataSize; + assembly { + returnDataSize := returndatasize() + } + bytes memory returnData = new bytes(returnDataSize); + assembly { + returndatacopy(add(returnData, 0x20), 0, returnDataSize) + switch success + case 0 { + revert(add(returnData, 0x20), returnDataSize) + } + default { + return(add(returnData, 0x20), returnDataSize) + } + } + } +} diff --git a/system-contracts/hardhat.config.ts b/system-contracts/hardhat.config.ts new file mode 100644 index 000000000..e61fd22fd --- /dev/null +++ b/system-contracts/hardhat.config.ts @@ -0,0 +1,46 @@ +import "@matterlabs/hardhat-zksync-chai-matchers"; +import "@matterlabs/hardhat-zksync-node"; +import "@matterlabs/hardhat-zksync-solc"; +import "@nomiclabs/hardhat-ethers"; +import "hardhat-typechain"; + +export default { + zksolc: { + version: "1.3.18", + compilerSource: "binary", + settings: { + isSystem: true, + }, + }, + zkSyncDeploy: { + zkSyncNetwork: "http://localhost:3050", + ethNetwork: "http://localhost:8545", + }, + solidity: { + version: "0.8.20", + settings: { + optimizer: { + enabled: true, + runs: 9999999, + }, + outputSelection: { + "*": { + "*": ["storageLayout"], + }, + }, + }, + }, + networks: { + hardhat: { + zksync: true, + }, + zkSyncTestNode: { + url: "http://127.0.0.1:8011", + ethNetwork: "", + zksync: true, + }, + }, + paths: { + sources: "./contracts-preprocessed", + }, +}; diff --git a/system-contracts/package.json b/system-contracts/package.json new file mode 100644 index 000000000..bd347a7a4 --- /dev/null +++ b/system-contracts/package.json @@ -0,0 +1,66 @@ +{ + "name": "system-contracts", + "version": "0.1.0", + "repository": "git@github.com:matter-labs/system-contracts.git", + "license": "MIT", + "dependencies": { + "@matterlabs/hardhat-zksync-deploy": "^0.6.5", + "@nomiclabs/hardhat-solpp": "^2.0.1", + "commander": "^9.4.1", + "ethers": "^5.7.0", + "fast-glob": "^3.3.2", + "hardhat": "^2.18.3", + "preprocess": "^3.2.0", + "zksync-web3": "^0.14.3" + }, + "devDependencies": { + "@matterlabs/hardhat-zksync-chai-matchers": "^0.1.4", + "@matterlabs/hardhat-zksync-node": "^0.0.1-beta.7", + "@matterlabs/hardhat-zksync-solc": "^0.4.2", + "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", + "@nomiclabs/hardhat-ethers": "^2.0.0", + "@typechain/ethers-v5": "^2.0.0", + "@types/chai": "^4.2.21", + "@types/lodash": "^4.14.199", + "@types/mocha": "^8.2.3", + "@types/node": "^17.0.34", + "chai": "^4.3.4", + "hardhat-typechain": "^0.3.3", + "lodash": "^4.17.21", + "mocha": "^9.0.2", + "template-file": "^6.0.1", + "ts-generator": "^0.1.1", + "ts-node": "^10.1.0", + "typechain": "^4.0.0", + "typescript": "^4.6.4", + "zksync-ethers": "^5.0.0" + }, + "mocha": { + "timeout": 240000, + "exit": true, + "color": false, + "slow": 0, + "require": [ + "ts-node/register" + ] + }, + "scripts": { + "build": "yarn build:system-contracts && yarn build:bootloader", + "build:bootloader": "yarn preprocess:bootloader && yarn compile-yul compile-bootloader", + "build:system-contracts": "yarn preprocess:system-contracts && hardhat compile && yarn compile-yul compile-precompiles", + "build:test-system-contracts": "yarn preprocess:system-contracts --test-mode && hardhat compile && yarn compile-yul compile-precompiles && yarn compile-zasm", + "calculate-hashes:check": "ts-node scripts/calculate-hashes.ts --check-only", + "calculate-hashes:fix": "ts-node scripts/calculate-hashes.ts", + "clean": "yarn clean:bootloader && yarn clean:system-contracts", + "clean:bootloader": "rm -rf ./bootloader/build ./bootloader/tests/artifacts", + "clean:system-contracts": "rm -rf ./contracts-preprocessed && hardhat clean", + "compile-yul": "ts-node scripts/compile-yul.ts", + "compile-zasm": "ts-node scripts/compile-zasm.ts", + "deploy-preimages": "ts-node scripts/deploy-preimages.ts", + "preprocess:bootloader": "rm -rf ./bootloader/build && yarn ts-node scripts/preprocess-bootloader.ts", + "preprocess:system-contracts": "rm -rf ./contracts-preprocessed && ts-node scripts/preprocess-system-contracts.ts", + "test": "yarn build:test-system-contracts && hardhat test --network zkSyncTestNode", + "test-node": "hardhat node-zksync --tag v0.0.1-alpha.boojum", + "test:bootloader": "cd bootloader/test_infra && cargo run" + } +} diff --git a/system-contracts/scripts/calculate-hashes.ts b/system-contracts/scripts/calculate-hashes.ts new file mode 100644 index 000000000..1fe368d75 --- /dev/null +++ b/system-contracts/scripts/calculate-hashes.ts @@ -0,0 +1,241 @@ +import { ethers } from "ethers"; +import * as fs from "fs"; +import _ from "lodash"; +import os from "os"; +import { join } from "path"; +import { hashBytecode } from "zksync-web3/build/src/utils"; + +type ContractDetails = { + contractName: string; + bytecodePath: string; + sourceCodePath: string; +}; + +type Hashes = { + bytecodeHash: string; + sourceCodeHash: string; +}; + +type SystemContractHashes = ContractDetails & Hashes; + +const findDirsEndingWith = (path: string, endingWith: string): string[] => { + const absolutePath = makePathAbsolute(path); + try { + const dirs = fs.readdirSync(absolutePath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()); + const dirsEndingWithSol = dirs.filter((dirent) => dirent.name.endsWith(endingWith)); + return dirsEndingWithSol.map((dirent) => dirent.name); + } catch (err) { + const msg = err instanceof Error ? err.message : "Unknown error"; + throw new Error(`Failed to read directory: ${absolutePath} Error: ${msg}`); + } +}; + +const findFilesEndingWith = (path: string, endingWith: string): string[] => { + const absolutePath = makePathAbsolute(path); + try { + const files = fs.readdirSync(absolutePath, { withFileTypes: true }).filter((dirent) => dirent.isFile()); + const filesEndingWithSol = files.filter((dirent) => dirent.name.endsWith(endingWith)); + return filesEndingWithSol.map((dirent) => dirent.name); + } catch (err) { + const msg = err instanceof Error ? err.message : "Unknown error"; + throw new Error(`Failed to read directory: ${absolutePath} Error: ${msg}`); + } +}; + +const SOLIDITY_ARTIFACTS_DIR = "artifacts-zk"; + +const getSolidityContractDetails = (dir: string, contractName: string): ContractDetails => { + const bytecodePath = join(SOLIDITY_ARTIFACTS_DIR, dir, contractName + ".sol", contractName + ".json"); + const sourceCodePath = join(dir, contractName + ".sol"); + return { + contractName, + bytecodePath, + sourceCodePath, + }; +}; + +const getSolidityContractsDetails = (dir: string): ContractDetails[] => { + const bytecodesDir = join(SOLIDITY_ARTIFACTS_DIR, dir); + const dirsEndingWithSol = findDirsEndingWith(bytecodesDir, ".sol"); + const contractNames = dirsEndingWithSol.map((d) => d.replace(".sol", "")); + const solidityContractsDetails = contractNames.map((c) => getSolidityContractDetails(dir, c)); + return solidityContractsDetails; +}; + +const YUL_ARTIFACTS_DIR = "artifacts"; + +const getYulContractDetails = (dir: string, contractName: string): ContractDetails => { + const bytecodePath = join(dir, YUL_ARTIFACTS_DIR, contractName + ".yul.zbin"); + const sourceCodePath = join(dir, contractName + ".yul"); + return { + contractName, + bytecodePath, + sourceCodePath, + }; +}; + +const getYulContractsDetails = (dir: string): ContractDetails[] => { + const dirsEndingWithYul = findFilesEndingWith(dir, ".yul"); + const contractNames = dirsEndingWithYul.map((d) => d.replace(".yul", "")); + const yulContractsDetails = contractNames.map((c) => getYulContractDetails(dir, c)); + return yulContractsDetails; +}; + +const makePathAbsolute = (path: string): string => { + return join(__dirname, "..", path); +}; + +const readSourceCode = (details: ContractDetails): string => { + const absolutePath = makePathAbsolute(details.sourceCodePath); + try { + return ethers.utils.hexlify(fs.readFileSync(absolutePath)); + } catch (err) { + const msg = err instanceof Error ? err.message : "Unknown error"; + throw new Error(`Failed to read source code for ${details.contractName}: ${absolutePath} Error: ${msg}`); + } +}; + +const readBytecode = (details: ContractDetails): string => { + const absolutePath = makePathAbsolute(details.bytecodePath); + try { + if (details.bytecodePath.endsWith(".json")) { + const jsonFile = fs.readFileSync(absolutePath, "utf8"); + return ethers.utils.hexlify(JSON.parse(jsonFile).bytecode); + } else { + return ethers.utils.hexlify(fs.readFileSync(absolutePath)); + } + } catch (err) { + const msg = err instanceof Error ? err.message : "Unknown error"; + throw new Error(`Failed to read bytecode for ${details.contractName}: ${details.bytecodePath} Error: ${msg}`); + } +}; + +const getHashes = (contractName: string, sourceCode: string, bytecode: string): Hashes => { + try { + return { + bytecodeHash: ethers.utils.hexlify(hashBytecode(bytecode)), + // The extra checks performed by the hashBytecode function are not needed for the source code, therefore + // sha256 is used for simplicity + sourceCodeHash: ethers.utils.sha256(sourceCode), + }; + } catch (err) { + const msg = err instanceof Error ? err.message : "Unknown error"; + throw new Error(`Failed to calculate hashes for ${contractName} Error: ${msg}`); + } +}; + +const getSystemContractsHashes = (systemContractsDetails: ContractDetails[]): SystemContractHashes[] => + systemContractsDetails.map((contractDetails) => { + const sourceCode = readSourceCode(contractDetails); + const bytecode = readBytecode(contractDetails); + const hashes = getHashes(contractDetails.contractName, sourceCode, bytecode); + + const systemContractHashes: SystemContractHashes = { + ...contractDetails, + ...hashes, + }; + + return systemContractHashes; + }); + +const readSystemContractsHashesFile = (path: string): SystemContractHashes[] => { + const absolutePath = makePathAbsolute(path); + try { + const file = fs.readFileSync(absolutePath, "utf8"); + const parsedFile = JSON.parse(file); + return parsedFile; + } catch (err) { + const msg = err instanceof Error ? err.message : "Unknown error"; + throw new Error(`Failed to read file: ${absolutePath} Error: ${msg}`); + } +}; + +const saveSystemContractsHashesFile = (path: string, systemContractsHashes: SystemContractHashes[]) => { + const absolutePath = makePathAbsolute(path); + try { + fs.writeFileSync(absolutePath, JSON.stringify(systemContractsHashes, null, 2) + os.EOL); + } catch (err) { + const msg = err instanceof Error ? err.message : "Unknown error"; + throw new Error(`Failed to save file: ${absolutePath} Error: ${msg}`); + } +}; + +const findDifferences = (newHashes: SystemContractHashes[], oldHashes: SystemContractHashes[]) => { + const differentElements = _.xorWith(newHashes, oldHashes, _.isEqual); + + const differentUniqueElements = _.uniqWith(differentElements, (a, b) => a.contractName === b.contractName); + + const differencesList = differentUniqueElements.map((diffElem) => { + const newHashesElem = newHashes.find((elem) => elem.contractName === diffElem.contractName); + + const oldHashesElem = oldHashes.find((elem) => elem.contractName === diffElem.contractName); + + const differingFields = _.xorWith( + Object.entries(newHashesElem || {}), + Object.entries(oldHashesElem || {}), + _.isEqual + ); + + const differingFieldsUniqueKeys = _.uniq(differingFields.map(([key]) => key)); + + return { + contract: diffElem.contractName, + differingFields: differingFieldsUniqueKeys, + old: oldHashesElem || {}, + new: newHashesElem || {}, + }; + }); + + return differencesList; +}; + +const SOLIDITY_SOURCE_CODE_PATHS = ["contracts-preprocessed"]; +const YUL_SOURCE_CODE_PATHS = ["contracts-preprocessed", "contracts-preprocessed/precompiles", "bootloader/build"]; +const OUTPUT_FILE_PATH = "SystemContractsHashes.json"; + +const main = async () => { + const args = process.argv; + if (args.length > 3 || (args.length == 3 && !args.includes("--check-only"))) { + console.log( + "This command can be used with no arguments or with the --check-only flag. Use the --check-only flag to check the hashes without updating the SystemContractsHashes.json file." + ); + process.exit(1); + } + const checkOnly = args.includes("--check-only"); + + const solidityContractsDetails = _.flatten(SOLIDITY_SOURCE_CODE_PATHS.map(getSolidityContractsDetails)); + const yulContractsDetails = _.flatten(YUL_SOURCE_CODE_PATHS.map(getYulContractsDetails)); + const systemContractsDetails = [...solidityContractsDetails, ...yulContractsDetails]; + + const newSystemContractsHashes = getSystemContractsHashes(systemContractsDetails); + const oldSystemContractsHashes = readSystemContractsHashesFile(OUTPUT_FILE_PATH); + if (_.isEqual(newSystemContractsHashes, oldSystemContractsHashes)) { + console.log("Calculated hashes match the hashes in the SystemContractsHashes.json file."); + console.log("Exiting..."); + return; + } + const differences = findDifferences(newSystemContractsHashes, oldSystemContractsHashes); + console.log("Calculated hashes differ from the hashes in the SystemContractsHashes.json file. Differences:"); + console.log(differences); + if (checkOnly) { + console.log( + "You can use the `yarn sc calculate-hashes:fix` command to update the SystemContractsHashes.json file." + ); + console.log("Exiting..."); + process.exit(1); + } else { + console.log("Updating..."); + saveSystemContractsHashesFile(OUTPUT_FILE_PATH, newSystemContractsHashes); + console.log("Update finished"); + console.log("Exiting..."); + return; + } +}; + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err.message || err); + console.log("Please make sure to run `yarn sc build` before running this script."); + process.exit(1); + }); diff --git a/system-contracts/scripts/compile-yul.ts b/system-contracts/scripts/compile-yul.ts new file mode 100644 index 000000000..f237600f7 --- /dev/null +++ b/system-contracts/scripts/compile-yul.ts @@ -0,0 +1,47 @@ +import type { CompilerPaths } from "./utils"; +import { spawn, compilerLocation, prepareCompilerPaths } from "./utils"; +import * as fs from "fs"; +import { Command } from "commander"; + +const COMPILER_VERSION = "1.3.18"; +const IS_COMPILER_PRE_RELEASE = false; + +export async function compileYul(paths: CompilerPaths, file: string) { + const zksolcLocation = await compilerLocation(COMPILER_VERSION, IS_COMPILER_PRE_RELEASE); + await spawn( + `${zksolcLocation} ${paths.absolutePathSources}/${file} --optimization 3 --system-mode --yul --bin --overwrite -o ${paths.absolutePathArtifacts}` + ); +} + +export async function compileYulFolder(path: string) { + const paths = prepareCompilerPaths(path); + const files: string[] = (await fs.promises.readdir(path)).filter((fn) => fn.endsWith(".yul")); + for (const file of files) { + await compileYul(paths, `${file}`); + } +} + +async function main() { + const program = new Command(); + + program.version("0.1.0").name("compile yul").description("publish preimages for the L2 contracts"); + + program.command("compile-bootloader").action(async () => { + await compileYulFolder("bootloader/build"); + await compileYulFolder("bootloader/tests"); + }); + + program.command("compile-precompiles").action(async () => { + await compileYulFolder("contracts-preprocessed"); + await compileYulFolder("contracts-preprocessed/precompiles"); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err.message || err); + process.exit(1); + }); diff --git a/system-contracts/scripts/compile-zasm.ts b/system-contracts/scripts/compile-zasm.ts new file mode 100644 index 000000000..46e41ed9a --- /dev/null +++ b/system-contracts/scripts/compile-zasm.ts @@ -0,0 +1,33 @@ +import type { CompilerPaths } from "./utils"; +import { spawn, compilerLocation, prepareCompilerPaths } from "./utils"; +import * as fs from "fs"; + +const COMPILER_VERSION = "1.3.18"; +const IS_COMPILER_PRE_RELEASE = false; + +export async function compileZasm(paths: CompilerPaths, file: string) { + const zksolcLocation = await compilerLocation(COMPILER_VERSION, IS_COMPILER_PRE_RELEASE); + await spawn( + `${zksolcLocation} ${paths.absolutePathSources}/${file} --zkasm --bin --overwrite -o ${paths.absolutePathArtifacts}` + ); +} + +export async function compileZasmFolder(path: string) { + const paths = prepareCompilerPaths(path); + const files: string[] = (await fs.promises.readdir(path)).filter((fn) => fn.endsWith(".zasm")); + for (const file of files) { + await compileZasm(paths, `${file}`); + } +} + +// Currently used only for the test contracts +async function main() { + await compileZasmFolder("contracts-preprocessed/test-contracts"); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err.message || err); + process.exit(1); + }); diff --git a/system-contracts/scripts/constants.ts b/system-contracts/scripts/constants.ts new file mode 100644 index 000000000..9cd5675ce --- /dev/null +++ b/system-contracts/scripts/constants.ts @@ -0,0 +1,438 @@ +import type { BigNumberish, BytesLike } from "ethers"; +import { constants, ethers } from "ethers"; + +export const BOOTLOADER_FORMAL_ADDRESS = "0x0000000000000000000000000000000000008001"; +export const ETH_ADDRESS = constants.AddressZero; + +export enum Language { + Solidity = "solidity", + Yul = "yul", + Zasm = "zasm", +} + +export interface SystemContractDescription { + address: string; + codeName: string; +} + +export interface YulContractDescrption extends SystemContractDescription { + lang: Language.Yul; + path: string; +} + +// Currently used only for the tests +export interface ZasmContractDescrption extends SystemContractDescription { + lang: Language.Zasm; + path: string; +} + +export interface SolidityContractDescription extends SystemContractDescription { + lang: Language.Solidity; +} + +interface ISystemContracts { + [key: string]: YulContractDescrption | SolidityContractDescription; +} + +export const SYSTEM_CONTRACTS: ISystemContracts = { + zeroAddress: { + // zero address has EmptyContract code + address: "0x0000000000000000000000000000000000000000", + codeName: "EmptyContract", + lang: Language.Solidity, + }, + ecrecover: { + address: "0x0000000000000000000000000000000000000001", + codeName: "Ecrecover", + lang: Language.Yul, + path: "precompiles", + }, + sha256: { + address: "0x0000000000000000000000000000000000000002", + codeName: "SHA256", + lang: Language.Yul, + path: "precompiles", + }, + ecAdd: { + address: "0x0000000000000000000000000000000000000006", + codeName: "EcAdd", + lang: Language.Yul, + path: "precompiles", + }, + ecMul: { + address: "0x0000000000000000000000000000000000000007", + codeName: "EcMul", + lang: Language.Yul, + path: "precompiles", + }, + bootloader: { + // Bootloader has EmptyContract code + address: "0x0000000000000000000000000000000000008001", + codeName: "EmptyContract", + lang: Language.Solidity, + }, + accountCodeStorage: { + address: "0x0000000000000000000000000000000000008002", + codeName: "AccountCodeStorage", + lang: Language.Solidity, + }, + nonceHolder: { + address: "0x0000000000000000000000000000000000008003", + codeName: "NonceHolder", + lang: Language.Solidity, + }, + knownCodesStorage: { + address: "0x0000000000000000000000000000000000008004", + codeName: "KnownCodesStorage", + lang: Language.Solidity, + }, + immutableSimulator: { + address: "0x0000000000000000000000000000000000008005", + codeName: "ImmutableSimulator", + lang: Language.Solidity, + }, + contractDeployer: { + address: "0x0000000000000000000000000000000000008006", + codeName: "ContractDeployer", + lang: Language.Solidity, + }, + l1Messenger: { + address: "0x0000000000000000000000000000000000008008", + codeName: "L1Messenger", + lang: Language.Solidity, + }, + msgValueSimulator: { + address: "0x0000000000000000000000000000000000008009", + codeName: "MsgValueSimulator", + lang: Language.Solidity, + }, + l2EthToken: { + address: "0x000000000000000000000000000000000000800a", + codeName: "L2EthToken", + lang: Language.Solidity, + }, + systemContext: { + address: "0x000000000000000000000000000000000000800b", + codeName: "SystemContext", + lang: Language.Solidity, + }, + bootloaderUtilities: { + address: "0x000000000000000000000000000000000000800c", + codeName: "BootloaderUtilities", + lang: Language.Solidity, + }, + eventWriter: { + address: "0x000000000000000000000000000000000000800d", + codeName: "EventWriter", + lang: Language.Yul, + path: "", + }, + compressor: { + address: "0x000000000000000000000000000000000000800e", + codeName: "Compressor", + lang: Language.Solidity, + }, + complexUpgrader: { + address: "0x000000000000000000000000000000000000800f", + codeName: "ComplexUpgrader", + lang: Language.Solidity, + }, + keccak256: { + address: "0x0000000000000000000000000000000000008010", + codeName: "Keccak256", + lang: Language.Yul, + path: "precompiles", + }, +} as const; + +export const EIP712_TX_ID = 113; +export const CHAIN_ID = 270; + +// For now, these types are hardcoded, but maybe it will make sense +export const EIP712_DOMAIN = { + name: "zkSync", + version: "2", + chainId: CHAIN_ID, + // zkSync contract doesn't verify EIP712 signatures. +}; + +export interface TransactionData { + txType: BigNumberish; + from: BigNumberish; + to: BigNumberish; + gasLimit: BigNumberish; + gasPerPubdataByteLimit: BigNumberish; + gasPrice: BigNumberish; + // In the future, we might want to add some + // new fields to the struct. The `txData` struct + // is to be passed to account and any changes to its structure + // would mean a breaking change to these accounts. In order to prevent this, + // we should keep some fields as "reserved". + // It is also recommended that their length is fixed, since + // it would allow easier proof integration (in case we will need + // some special circuit for preprocessing transactions). + reserved: BigNumberish[]; + data: BytesLike; + signature: BytesLike; + // Reserved dynamic type for the future use-case. Using it should be avoided, + // But it is still here, just in case we want to enable some additional functionality. + reservedDynamic: BytesLike; +} + +export interface EIP712Tx { + txType: BigNumberish; + from: BigNumberish; + to: BigNumberish; + value: BigNumberish; + gasLimit: BigNumberish; + gasPerPubdataByteLimit: BigNumberish; + gasPrice: BigNumberish; + nonce: BigNumberish; + data: BytesLike; + signature: BytesLike; +} + +export type Address = string; + +export const EIP712_TX_TYPE = { + Transaction: [ + { name: "txType", type: "uint8" }, + { name: "to", type: "uint256" }, + { name: "value", type: "uint256" }, + { name: "data", type: "bytes" }, + { name: "gasLimit", type: "uint256" }, + { name: "gasPerPubdataByteLimit", type: "uint256" }, + { name: "gasPrice", type: "uint256" }, + { name: "nonce", type: "uint256" }, + ], +}; + +export type DynamicType = "bytes" | "bytes32[]"; +export type FixedType = "address" | "uint256" | "uint128" | "uint32"; +export type FieldType = FixedType | DynamicType; + +function isDynamicType(x: FieldType): x is DynamicType { + return x == "bytes" || x == "bytes32[]"; +} + +function isFixedType(x: FieldType): x is FixedType { + return !isDynamicType(x); +} + +export const TransactionFields: Record = { + txType: "uint256", + from: "address", + to: "address", + gasLimit: "uint32", + gasPerPubdataByteLimit: "uint32", + maxFeePerGas: "uint256", + maxPriorityFeePerGas: "uint256", + paymaster: "address", + // In the future, we might want to add some + // new fields to the struct. The `txData` struct + // is to be passed to account and any changes to its structure + // would mean a breaking change to these accounts. In order to prevent this, + // we should keep some fields as "reserved". + // It is also recommended that their length is fixed, since + // it would allow easier proof integration (in case we will need + // some special circuit for preprocessing transactions). + reserved: Array(6).fill("uint256"), + data: "bytes", + signature: "bytes", + factoryDeps: "bytes32[]", + paymasterInput: "bytes", + // Reserved dynamic type for the future use-case. Using it should be avoided, + // But it is still here, just in case we want to enable some additional functionality. + reservedDynamic: "bytes", +}; + +function capitalize(s: string) { + if (!s.length) { + return s; + } + return `${s[0].toUpperCase()}${s.substring(1)}`; +} + +function memPosFromOffset(offset: number) { + return offset === 0 ? "innerTxDataOffset" : `add(innerTxDataOffset, ${offset})`; +} + +function getGetterName(fieldName: string) { + return `get${capitalize(fieldName)}`; +} + +function getPtrGetterName(fieldName: string) { + return `get${capitalize(fieldName)}Ptr`; +} + +function getGetter(fieldName: string, offset: number) { + const getterName = getGetterName(fieldName); + const memPos = memPosFromOffset(offset); + return ` + function ${getterName}(innerTxDataOffset) -> ret { + ret := mload(${memPos}) + } + `; +} + +function getPtrGetter(fieldName: string, offset: number) { + const getterName = getPtrGetterName(fieldName); + const memPos = memPosFromOffset(offset); + return ` + function ${getterName}(innerTxDataOffset) -> ret { + ret := mload(${memPos}) + ret := add(innerTxDataOffset, ret) + } + `; +} + +function getTypeValidationMethodName(type: FieldType) { + if (type == "bytes32[]") { + return "validateBytes32Array"; + } else { + return `validate${capitalize(type)}`; + } +} + +function getBytesLengthGetterName(fieldName: string): string { + return `get${capitalize(fieldName)}BytesLength`; +} + +function getBytesLengthGetter(fieldName: string, type: DynamicType) { + let lengthToBytes: string; + if (type == "bytes") { + lengthToBytes = "lengthToWords(mload(ptr))"; + } else if (type == "bytes32[]") { + lengthToBytes = "mul(mload(ptr),32)"; + } else { + throw new Error(`Type ${type} is not supported`); + } + + const getterName = getBytesLengthGetterName(fieldName); + return ` + function ${getterName}(innerTxDataOffset) -> ret { + let ptr := ${getPtrGetterName(fieldName)}(innerTxDataOffset) + ret := ${lengthToBytes} + } + `; +} + +function getDataLength(baseLength: number, dynamicFields: [string, DynamicType][]) { + const ptrAdders = dynamicFields + .map(([fieldName]) => { + return ` + ret := add(ret, ${getBytesLengthGetterName(fieldName)}(innerTxDataOffset))`; + }) + .join(""); + + return ` + function getDataLength(innerTxDataOffset) -> ret { + // To get the length of the txData in bytes, we can simply + // get the number of fields * 32 + the length of the dynamic types + // in bytes. + ret := ${baseLength + dynamicFields.length * 32} + + ${ptrAdders} + } + `; +} + +function validateFixedSizeField(fieldName: string, type: FixedType): string { + if (type == "uint256") { + // There is no validation for uint256 + return ""; + } + const assertionErrorStr = getEncodingError(fieldName); + const fieldValue = `${fieldName}Value`; + return ` + let ${fieldValue} := ${getGetterName(fieldName)}(innerTxDataOffset) + if iszero(${getTypeValidationMethodName(type)}(${fieldValue})) { + assertionError("${assertionErrorStr}") + } + `; +} + +function getEncodingError(fieldName: string) { + // Unfortunately we have to keep this not-so-readable name + // because the maximum length is 32. + const assertionError = `Encoding ${fieldName}`; + + if (assertionError.length > 32) { + throw new Error(`Assertion str too long: ${assertionError}`); + } + + return assertionError; +} + +function getValidateTxStructure( + fixedFieldsChecks: string, + fixedLenPart: number, + dynamicFields: [string, DynamicType][] +): string { + const dynamicChecks = dynamicFields + .map(([fieldName, type]) => { + const lengthPos = `${fieldName}LengthPos`; + const assertionError = getEncodingError(fieldName); + const validationMethod = getTypeValidationMethodName(type); + + return ` + let ${lengthPos} := ${getPtrGetterName(fieldName)}(innerTxDataOffset) + if iszero(eq(${lengthPos}, expectedDynamicLenPtr)) { + assertionError("${assertionError}") + } + expectedDynamicLenPtr := ${validationMethod}(${lengthPos}) + `; + }) + .join("\n"); + + return ` + /// This method checks that the transaction's structure is correct + /// and tightly packed + function validateAbiEncoding(innerTxDataOffset) -> ret { + ${fixedFieldsChecks} + + let expectedDynamicLenPtr := add(innerTxDataOffset, ${fixedLenPart}) + ${dynamicChecks} + }`; +} + +export function getTransactionUtils(): string { + let result = `/// + /// TransactionData utilities + ///\n`; + + let innerOffsetBytes = 0; + let checksStr = ""; + + const dynamicFields: [string, DynamicType][] = []; + for (const [key, value] of Object.entries(TransactionFields)) { + if (Array.isArray(value)) { + // We assume that the + for (let i = 0; i < value.length; i++) { + const keyName = `${key}${i}`; + result += getGetter(keyName, innerOffsetBytes); + checksStr += validateFixedSizeField(keyName, value[i]); + innerOffsetBytes += 32; + } + } else if (isFixedType(value)) { + result += getGetter(key, innerOffsetBytes); + checksStr += validateFixedSizeField(key, value); + innerOffsetBytes += 32; + } else { + result += getPtrGetter(key, innerOffsetBytes); + result += getBytesLengthGetter(key, value); + dynamicFields.push([key, value]); + innerOffsetBytes += 32; + } + } + + result += getValidateTxStructure(checksStr, innerOffsetBytes, dynamicFields); + + result += getDataLength(innerOffsetBytes, dynamicFields); + + return result; +} + +export function getRevertSelector(): string { + return ethers.utils.keccak256(ethers.utils.toUtf8Bytes("Error(string)")).substring(0, 10); +} diff --git a/system-contracts/scripts/deploy-preimages.ts b/system-contracts/scripts/deploy-preimages.ts new file mode 100644 index 000000000..4f45ef567 --- /dev/null +++ b/system-contracts/scripts/deploy-preimages.ts @@ -0,0 +1,366 @@ +import * as hre from "hardhat"; + +import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; +import { Command } from "commander"; +import type { BigNumber, BytesLike } from "ethers"; +import { ethers } from "ethers"; +import { formatUnits, parseUnits } from "ethers/lib/utils"; +import * as fs from "fs"; +import * as path from "path"; +import type { types } from "zksync-web3"; +import { Provider, Wallet } from "zksync-web3"; +import { hashBytecode } from "zksync-web3/build/src/utils"; +import { Language, SYSTEM_CONTRACTS } from "./constants"; +import type { Dependency, DeployedDependency } from "./utils"; +import { checkMarkers, filterPublishedFactoryDeps, getBytecodes, publishFactoryDeps, readYulBytecode } from "./utils"; + +const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant"); +const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); + +// Maximum length of the combined length of dependencies +const MAX_COMBINED_LENGTH = 90000; + +const DEFAULT_ACCOUNT_CONTRACT_NAME = "DefaultAccount"; +const BOOTLOADER_CONTRACT_NAME = "Bootloader"; + +const CONSOLE_COLOR_RESET = "\x1b[0m"; +const CONSOLE_COLOR_RED = "\x1b[31m"; +const CONSOLE_COLOR_GREEN = "\x1b[32m"; + +interface TransactionReport { + msg: string; + success: boolean; +} + +class PublishReporter { + // Promises for pending L1->L2 transactions with submitted bytecode hashes. + // Each promise will return either string with error or null denoting success. + pendingPromises: Promise[] = []; + + async appendPublish(bytecodes: BytesLike[], deployer: Deployer, transaction: types.PriorityOpResponse) { + const waitAndDoubleCheck = async () => { + // Waiting for the transaction to be processed by the server + await transaction.wait(); + + // Double checking that indeed the dependencies have been marked as known + await checkMarkers(bytecodes, deployer); + }; + + this.pendingPromises.push( + waitAndDoubleCheck() + .catch((err) => { + return Promise.resolve({ + msg: `Transaction ${transaction.hash} failed with ${err.message || err}`, + success: false, + }); + }) + .then(() => { + return Promise.resolve({ + msg: `Transaction ${transaction.hash} was successful`, + success: true, + }); + }) + ); + } + + async report() { + const results = await Promise.all(this.pendingPromises); + results.forEach((result) => { + if (result.success) { + console.log(CONSOLE_COLOR_GREEN + result.msg + CONSOLE_COLOR_RESET); + } else { + console.log(CONSOLE_COLOR_RED + result.msg + CONSOLE_COLOR_RESET); + } + }); + } +} + +class ZkSyncDeployer { + deployer: Deployer; + gasPrice: BigNumber; + nonce: number; + dependenciesToUpgrade: DeployedDependency[]; + defaultAccountToUpgrade?: DeployedDependency; + bootloaderToUpgrade?: DeployedDependency; + reporter: PublishReporter; + constructor(deployer: Deployer, gasPrice: BigNumber, nonce: number) { + this.deployer = deployer; + this.gasPrice = gasPrice; + this.nonce = nonce; + this.dependenciesToUpgrade = []; + this.reporter = new PublishReporter(); + } + + async publishFactoryDeps(dependencies: Dependency[]) { + if (dependencies.length === 0) { + return; + } + + const priorityOpHandle = await publishFactoryDeps(dependencies, this.deployer, this.nonce, this.gasPrice); + + await this.reporter.appendPublish(getBytecodes(dependencies), this.deployer, priorityOpHandle); + this.nonce += 1; + } + + // Returns the current default account bytecode on zkSync + async currentDefaultAccountBytecode(): Promise { + const zkSync = await this.deployer.zkWallet.getMainContract(); + return await zkSync.getL2DefaultAccountBytecodeHash(); + } + + // If needed, appends the default account bytecode to the upgrade + async checkShouldUpgradeDefaultAA(defaultAccountBytecode: string) { + const bytecodeHash = ethers.utils.hexlify(hashBytecode(defaultAccountBytecode)); + const currentDefaultAccountBytecode = ethers.utils.hexlify(await this.currentDefaultAccountBytecode()); + + // If the bytecode is not the same as the one deployed on zkSync, we need to add it to the deployment + if (bytecodeHash.toLowerCase() !== currentDefaultAccountBytecode) { + this.defaultAccountToUpgrade = { + name: DEFAULT_ACCOUNT_CONTRACT_NAME, + bytecodeHashes: [bytecodeHash], + }; + } + } + + // Publish default account bytecode + async publishDefaultAA(defaultAccountBytecode: string) { + const [defaultAccountBytecodes] = await filterPublishedFactoryDeps( + DEFAULT_ACCOUNT_CONTRACT_NAME, + [defaultAccountBytecode], + this.deployer + ); + + if (defaultAccountBytecodes.length == 0) { + console.log("Default account bytecode is already published, skipping"); + return; + } + + await this.publishFactoryDeps([ + { + name: DEFAULT_ACCOUNT_CONTRACT_NAME, + bytecodes: defaultAccountBytecodes, + }, + ]); + } + + // Publishes the bytecode of default AA and appends it to the deployed bytecodes if needed. + async processDefaultAA() { + const defaultAccountBytecode = (await this.deployer.loadArtifact(DEFAULT_ACCOUNT_CONTRACT_NAME)).bytecode; + + await this.publishDefaultAA(defaultAccountBytecode); + await this.checkShouldUpgradeDefaultAA(defaultAccountBytecode); + } + + async currentBootloaderBytecode(): Promise { + const zkSync = await this.deployer.zkWallet.getMainContract(); + return await zkSync.getL2BootloaderBytecodeHash(); + } + + async checkShouldUpgradeBootloader(bootloaderCode: string) { + const bytecodeHash = ethers.utils.hexlify(hashBytecode(bootloaderCode)); + const currentBootloaderBytecode = ethers.utils.hexlify(await this.currentBootloaderBytecode()); + + // If the bytecode is not the same as the one deployed on zkSync, we need to add it to the deployment + if (bytecodeHash.toLowerCase() !== currentBootloaderBytecode) { + this.bootloaderToUpgrade = { + name: BOOTLOADER_CONTRACT_NAME, + bytecodeHashes: [bytecodeHash], + }; + } + } + + async publishBootloader(bootloaderCode: string) { + console.log("\nPublishing bootloader bytecode:"); + + const [deps] = await filterPublishedFactoryDeps(BOOTLOADER_CONTRACT_NAME, [bootloaderCode], this.deployer); + + if (deps.length == 0) { + console.log("Default bootloader bytecode is already published, skipping"); + return; + } + + await this.publishFactoryDeps([ + { + name: BOOTLOADER_CONTRACT_NAME, + bytecodes: deps, + }, + ]); + } + + async processBootloader() { + const bootloaderCode = ethers.utils.hexlify(fs.readFileSync("./bootloader/build/artifacts/proved_batch.yul.zbin")); + + await this.publishBootloader(bootloaderCode); + await this.checkShouldUpgradeBootloader(bootloaderCode); + } + + async shouldUpgradeSystemContract(contractAddress: string, expectedBytecodeHash: string): Promise { + // We could have also used the `getCode` method of the JSON-RPC, but in the context + // of system upgrades looking into account code storage is more robust + const currentBytecodeHash = await this.deployer.zkWallet.provider.getStorageAt( + SYSTEM_CONTRACTS.accountCodeStorage.address, + contractAddress + ); + + return expectedBytecodeHash.toLowerCase() !== currentBytecodeHash.toLowerCase(); + } + + // Returns the contracts to be published. + async prepareContractsForPublishing(): Promise { + const dependenciesToPublish: Dependency[] = []; + for (const contract of Object.values(SYSTEM_CONTRACTS)) { + const contractName = contract.codeName; + let factoryDeps: string[] = []; + if (contract.lang == Language.Solidity) { + const artifact = await this.deployer.loadArtifact(contractName); + factoryDeps = [...(await this.deployer.extractFactoryDeps(artifact)), artifact.bytecode]; + } else { + // Yul files have only one dependency + factoryDeps = [readYulBytecode(contract)]; + } + + const contractBytecodeHash = ethers.utils.hexlify(hashBytecode(factoryDeps[factoryDeps.length - 1])); + if (await this.shouldUpgradeSystemContract(contract.address, contractBytecodeHash)) { + this.dependenciesToUpgrade.push({ + name: contractName, + bytecodeHashes: [contractBytecodeHash], + address: contract.address, + }); + } + + const [bytecodesToPublish, currentLength] = await filterPublishedFactoryDeps( + contractName, + factoryDeps, + this.deployer + ); + if (bytecodesToPublish.length == 0) { + console.log(`All bytecodes for ${contractName} are already published, skipping`); + continue; + } + if (currentLength > MAX_COMBINED_LENGTH) { + throw new Error(`Can not publish dependencies of contract ${contractName}`); + } + + dependenciesToPublish.push({ + name: contractName, + bytecodes: bytecodesToPublish, + address: contract.address, + }); + } + + return dependenciesToPublish; + } + + async publishDependencies(dependenciesToPublish: Dependency[]) { + let currentLength = 0; + let currentDependencies: Dependency[] = []; + // We iterate over dependencies and try to batch the publishing of those in order to save up on gas as well as time. + for (const dependency of dependenciesToPublish) { + const dependencyLength = dependency.bytecodes.reduce((prev, dep) => prev + ethers.utils.arrayify(dep).length, 0); + if (currentLength + dependencyLength > MAX_COMBINED_LENGTH) { + await this.publishFactoryDeps(currentDependencies); + currentLength = dependencyLength; + currentDependencies = [dependency]; + } else { + currentLength += dependencyLength; + currentDependencies.push(dependency); + } + } + if (currentDependencies.length > 0) { + await this.publishFactoryDeps(currentDependencies); + } + } + + returnResult() { + return { + systemContracts: this.dependenciesToUpgrade, + defaultAA: this.defaultAccountToUpgrade, + bootloader: this.bootloaderToUpgrade, + }; + } +} + +export function l1RpcUrl() { + return process.env.ETH_CLIENT_WEB3_URL as string; +} + +export function l2RpcUrl() { + return process.env.API_WEB3_JSON_RPC_HTTP_URL as string; +} + +async function main() { + const program = new Command(); + + program.version("0.1.0").name("publish preimages").description("publish preimages for the L2 contracts"); + + program + .option("--private-key ") + .option("--gas-price ") + .option("--nonce ") + .option("--l1Rpc ") + .option("--l2Rpc ") + .option("--bootloader") + .option("--default-aa") + .option("--system-contracts") + .option("--file ") + .action(async (cmd) => { + const l1Rpc = cmd.l1Rpc ? cmd.l1Rpc : l1RpcUrl(); + const l2Rpc = cmd.l2Rpc ? cmd.l2Rpc : l2RpcUrl(); + const providerL1 = new ethers.providers.JsonRpcProvider(l1Rpc); + const providerL2 = new Provider(l2Rpc); + const wallet = cmd.privateKey + ? new Wallet(cmd.privateKey) + : Wallet.fromMnemonic(process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, "m/44'/60'/0'/0/1"); + wallet.connect(providerL2); + wallet.connectToL1(providerL1); + + // TODO(EVM-392): refactor to avoid `any` here. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const deployer = new Deployer(hre, wallet as any); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + deployer.zkWallet = deployer.zkWallet.connect(providerL2 as any).connectToL1(providerL1); + deployer.ethWallet = deployer.ethWallet.connect(providerL1); + const ethWallet = deployer.ethWallet; + + console.log(`Using deployer wallet: ${ethWallet.address}`); + + const gasPrice = cmd.gasPrice ? parseUnits(cmd.gasPrice, "gwei") : await providerL1.getGasPrice(); + console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); + + const nonce = cmd.nonce ? parseInt(cmd.nonce) : await ethWallet.getTransactionCount(); + console.log(`Using nonce: ${nonce}`); + + const zkSyncDeployer = new ZkSyncDeployer(deployer, gasPrice, nonce); + if (cmd.bootloader) { + await zkSyncDeployer.processBootloader(); + } + + if (cmd.defaultAa) { + await zkSyncDeployer.processDefaultAA(); + } + + if (cmd.systemContracts) { + const dependenciesToPublish = await zkSyncDeployer.prepareContractsForPublishing(); + await zkSyncDeployer.publishDependencies(dependenciesToPublish); + } + + console.log("\nSending all L1->L2 transactions done. Now waiting for the reports on those...\n"); + await zkSyncDeployer.reporter.report(); + + const result = zkSyncDeployer.returnResult(); + console.log(JSON.stringify(result, null, 2)); + if (cmd.file) { + fs.writeFileSync(cmd.file, JSON.stringify(result, null, 2)); + } + console.log("\nPublishing factory dependencies complete!"); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); diff --git a/system-contracts/scripts/preprocess-bootloader.ts b/system-contracts/scripts/preprocess-bootloader.ts new file mode 100644 index 000000000..c95c33c8a --- /dev/null +++ b/system-contracts/scripts/preprocess-bootloader.ts @@ -0,0 +1,265 @@ +import * as hre from "hardhat"; + +import { ethers } from "ethers"; +import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs"; +import { render, renderFile } from "template-file"; +import { utils } from "zksync-web3"; +import { SYSTEM_CONTRACTS, getRevertSelector, getTransactionUtils } from "./constants"; +import type { ForceDeployment } from "./utils"; + +/* eslint-disable @typescript-eslint/no-var-requires */ +const preprocess = require("preprocess"); +const SYSTEM_PARAMS = require("../SystemConfig.json"); +/* eslint-enable@typescript-eslint/no-var-requires */ + +const OUTPUT_DIR = "bootloader/build"; + +const PREPROCCESING_MODES = ["proved_batch", "playground_batch"]; + +function getSelector(contractName: string, method: string): string { + const artifact = hre.artifacts.readArtifactSync(contractName); + const contractInterface = new ethers.utils.Interface(artifact.abi); + + return contractInterface.getSighash(method); +} + +// Methods from ethers do zero pad from left, but we need to pad from the right +function padZeroRight(hexData: string, length: number): string { + while (hexData.length < length) { + hexData += "0"; + } + + return hexData; +} + +const PADDED_SELECTOR_LENGTH = 32 * 2 + 2; +function getPaddedSelector(contractName: string, method: string): string { + const result = getSelector(contractName, method); + + return padZeroRight(result, PADDED_SELECTOR_LENGTH); +} + +function getSystemContextExpectedHash() { + const artifact = hre.artifacts.readArtifactSync("SystemContext"); + return ethers.utils.hexlify(utils.hashBytecode(artifact.bytecode)); +} + +function upgradeSystemContextCalldata() { + // Here we need to encode the force deployment for the system context contract as well as transform + // it into writing of the calldata into the bootloader memory. + + const newHash = getSystemContextExpectedHash(); + const artifact = new ethers.utils.Interface(hre.artifacts.readArtifactSync("ContractDeployer").abi); + + const forceDeplyment: ForceDeployment = { + bytecodeHash: newHash, + newAddress: SYSTEM_CONTRACTS.systemContext.address, + callConstructor: false, + value: 0, + input: "0x", + }; + + let calldata = artifact.encodeFunctionData("forceDeployOnAddresses", [[forceDeplyment]]); + const originalLength = (calldata.length - 2) / 2; + + // Padding calldata from the right. We really need to do it, since Yul would "implicitly" pad it from the left and it + // it is not what we want. + while ((calldata.length - 2) % 64 != 0) { + calldata += "0"; + } + + // We will apply tabulation to make the compiled bootloader code more readable + const TABULATION = "\t\t\t\t\t"; + // In the first slot we need to store the calldata's length + let data = `mstore(0x00, ${originalLength})\n`; + + const slices = (calldata.length - 2) / 64; + + for (let slice = 0; slice < slices; slice++) { + const offset = slice * 32; + const sliceHex = calldata.slice(2 + offset * 2, 2 + offset * 2 + 64); + + data += `${TABULATION}mstore(${offset + 32}, 0x${sliceHex})\n`; + } + + return data; +} + +// Maybe in the future some of these params will be passed +// in a JSON file. For now, a simple object is ok here. +const params = { + MARK_BATCH_AS_REPUBLISHED_SELECTOR: getSelector("KnownCodesStorage", "markFactoryDeps"), + VALIDATE_TX_SELECTOR: getSelector("IAccount", "validateTransaction"), + EXECUTE_TX_SELECTOR: getSelector("DefaultAccount", "executeTransaction"), + RIGHT_PADDED_GET_ACCOUNT_VERSION_SELECTOR: getPaddedSelector("ContractDeployer", "extendedAccountVersion"), + RIGHT_PADDED_GET_RAW_CODE_HASH_SELECTOR: getPaddedSelector("AccountCodeStorage", "getRawCodeHash"), + PAY_FOR_TX_SELECTOR: getSelector("DefaultAccount", "payForTransaction"), + PRE_PAYMASTER_SELECTOR: getSelector("DefaultAccount", "prepareForPaymaster"), + VALIDATE_AND_PAY_PAYMASTER: getSelector("IPaymaster", "validateAndPayForPaymasterTransaction"), + // It doesn't used directly now but is important to keep the way to regenerate it when needed + TX_UTILITIES: getTransactionUtils(), + RIGHT_PADDED_POST_TRANSACTION_SELECTOR: getPaddedSelector("IPaymaster", "postTransaction"), + RIGHT_PADDED_SET_TX_ORIGIN: getPaddedSelector("SystemContext", "setTxOrigin"), + RIGHT_PADDED_SET_GAS_PRICE: getPaddedSelector("SystemContext", "setGasPrice"), + RIGHT_PADDED_INCREMENT_TX_NUMBER_IN_BLOCK_SELECTOR: getPaddedSelector("SystemContext", "incrementTxNumberInBatch"), + RIGHT_PADDED_RESET_TX_NUMBER_IN_BLOCK_SELECTOR: getPaddedSelector("SystemContext", "resetTxNumberInBatch"), + RIGHT_PADDED_SEND_L2_TO_L1_LOG_SELECTOR: getPaddedSelector("L1Messenger", "sendL2ToL1Log"), + PUBLISH_PUBDATA_SELECTOR: getSelector("L1Messenger", "publishPubdataAndClearState"), + RIGHT_PADDED_SET_NEW_BATCH_SELECTOR: getPaddedSelector("SystemContext", "setNewBatch"), + RIGHT_PADDED_OVERRIDE_BATCH_SELECTOR: getPaddedSelector("SystemContext", "unsafeOverrideBatch"), + // Error + REVERT_ERROR_SELECTOR: padZeroRight(getRevertSelector(), PADDED_SELECTOR_LENGTH), + RIGHT_PADDED_VALIDATE_NONCE_USAGE_SELECTOR: getPaddedSelector("INonceHolder", "validateNonceUsage"), + RIGHT_PADDED_MINT_ETHER_SELECTOR: getPaddedSelector("L2EthToken", "mint"), + GET_TX_HASHES_SELECTOR: getSelector("BootloaderUtilities", "getTransactionHashes"), + CREATE_SELECTOR: getSelector("ContractDeployer", "create"), + CREATE2_SELECTOR: getSelector("ContractDeployer", "create2"), + CREATE_ACCOUNT_SELECTOR: getSelector("ContractDeployer", "createAccount"), + CREATE2_ACCOUNT_SELECTOR: getSelector("ContractDeployer", "create2Account"), + PADDED_TRANSFER_FROM_TO_SELECTOR: getPaddedSelector("L2EthToken", "transferFromTo"), + SUCCESSFUL_ACCOUNT_VALIDATION_MAGIC_VALUE: getPaddedSelector("IAccount", "validateTransaction"), + SUCCESSFUL_PAYMASTER_VALIDATION_MAGIC_VALUE: getPaddedSelector("IPaymaster", "validateAndPayForPaymasterTransaction"), + PUBLISH_COMPRESSED_BYTECODE_SELECTOR: getSelector("Compressor", "publishCompressedBytecode"), + GET_MARKER_PADDED_SELECTOR: getPaddedSelector("KnownCodesStorage", "getMarker"), + RIGHT_PADDED_SET_L2_BLOCK_SELECTOR: getPaddedSelector("SystemContext", "setL2Block"), + RIGHT_PADDED_APPEND_TRANSACTION_TO_L2_BLOCK_SELECTOR: getPaddedSelector( + "SystemContext", + "appendTransactionToCurrentL2Block" + ), + RIGHT_PADDED_PUBLISH_TIMESTAMP_DATA_TO_L1_SELECTOR: getPaddedSelector("SystemContext", "publishTimestampDataToL1"), + COMPRESSED_BYTECODES_SLOTS: 32768, + ENSURE_RETURNED_MAGIC: 1, + FORBID_ZERO_GAS_PER_PUBDATA: 1, + SYSTEM_CONTEXT_EXPECTED_CODE_HASH: getSystemContextExpectedHash(), + UPGRADE_SYSTEM_CONTEXT_CALLDATA: upgradeSystemContextCalldata(), + // One of "worst case" scenarios for the number of state diffs in a batch is when 120kb of pubdata is spent + // on repeated writes, that are all zeroed out. In this case, the number of diffs is 120k / 5 = 24k. This means that they will have + // accoomdate 6528000 bytes of calldata for the uncompressed state diffs. Adding 120k on top leaves us with + // roughly 6650000 bytes needed for calldata. 207813 slots are needed to accomodate this amount of data. + // We round up to 208000 slots just in case. + // + // In theory though much more calldata could be used (if for instance 1 byte is used for enum index). It is the responsibility of the + // operator to ensure that it can form the correct calldata for the L1Messenger. + OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS: 208000, + ...SYSTEM_PARAMS, +}; + +function extractTestFunctionNames(sourceCode: string): string[] { + // Remove single-line comments + sourceCode = sourceCode.replace(/\/\/[^\n]*/g, ""); + + // Remove multi-line comments + sourceCode = sourceCode.replace(/\/\*[\s\S]*?\*\//g, ""); + + const regexPatterns = [/function\s+(TEST\w+)/g]; + + const results: string[] = []; + for (const pattern of regexPatterns) { + let match; + while ((match = pattern.exec(sourceCode)) !== null) { + results.push(match[1]); + } + } + + return [...new Set(results)]; // Remove duplicates +} + +function createTestFramework(tests: string[]): string { + let testFramework = ` + let test_id:= mload(0) + + switch test_id + case 0 { + testing_totalTests(${tests.length}) + } + `; + + tests.forEach((value, index) => { + testFramework += ` + case ${index + 1} { + testing_start("${value}") + ${value}() + } + `; + }); + + testFramework += ` + default { + } + return (0, 0) + `; + + return testFramework; +} + +function validateSource(source: string) { + const matches = source.matchAll(//g); + for (const match of matches) { + if (!PREPROCCESING_MODES.includes(match[1])) { + throw Error(`Invalid preprocessing mode '${match[1]}' at postion ${match.index}`); + } + } +} + +async function main() { + const bootloaderSource = readFileSync("bootloader/bootloader.yul").toString(); + validateSource(bootloaderSource); + + const bootloader = await render(bootloaderSource, params); + // The overhead is unknown for gas tests and so it should be zero to calculate it + const gasTestBootloaderTemplate = await render(bootloaderSource, { + ...params, + L2_TX_INTRINSIC_GAS: 0, + L2_TX_INTRINSIC_PUBDATA: 0, + L1_TX_INTRINSIC_L2_GAS: 0, + L1_TX_INTRINSIC_PUBDATA: 0, + FORBID_ZERO_GAS_PER_PUBDATA: 0, + }); + + const feeEstimationBootloaderTemplate = await render(bootloaderSource, { + ...params, + ENSURE_RETURNED_MAGIC: 0, + }); + + console.log("Preprocessing production bootloader"); + const provedBatchBootloader = preprocess.preprocess(bootloader, { BOOTLOADER_TYPE: "proved_batch" }); + console.log("Preprocessing playground block bootloader"); + const playgroundBatchBootloader = preprocess.preprocess(bootloader, { BOOTLOADER_TYPE: "playground_batch" }); + console.log("Preprocessing gas test bootloader"); + const gasTestBootloader = preprocess.preprocess(gasTestBootloaderTemplate, { BOOTLOADER_TYPE: "proved_batch" }); + console.log("Preprocessing fee estimation bootloader"); + const feeEstimationBootloader = preprocess.preprocess(feeEstimationBootloaderTemplate, { + BOOTLOADER_TYPE: "playground_batch", + }); + + console.log("Preprocessing bootloader tests"); + const bootloaderTests = await renderFile("bootloader/tests/bootloader/bootloader_test.yul", {}); + + const testMethods = extractTestFunctionNames(bootloaderTests); + + console.log("Found tests: " + testMethods); + + const testFramework = createTestFramework(testMethods); + + const bootloaderTestUtils = await renderFile("bootloader/tests/utils/test_utils.yul", {}); + + const bootloaderWithTests = await render(bootloaderSource, { + ...params, + CODE_START_PLACEHOLDER: "\n" + bootloaderTestUtils + "\n" + bootloaderTests + "\n" + testFramework, + }); + const provedBootloaderWithTests = preprocess.preprocess(bootloaderWithTests, { BOOTLOADER_TYPE: "proved_batch" }); + + if (!existsSync(OUTPUT_DIR)) { + mkdirSync(OUTPUT_DIR); + } + + writeFileSync(`${OUTPUT_DIR}/bootloader_test.yul`, provedBootloaderWithTests); + writeFileSync(`${OUTPUT_DIR}/proved_batch.yul`, provedBatchBootloader); + writeFileSync(`${OUTPUT_DIR}/playground_batch.yul`, playgroundBatchBootloader); + writeFileSync(`${OUTPUT_DIR}/gas_test.yul`, gasTestBootloader); + writeFileSync(`${OUTPUT_DIR}/fee_estimate.yul`, feeEstimationBootloader); + + console.log("Bootloader preprocessing done!"); +} + +main(); diff --git a/system-contracts/scripts/preprocess-system-contracts.ts b/system-contracts/scripts/preprocess-system-contracts.ts new file mode 100644 index 000000000..acecee1ac --- /dev/null +++ b/system-contracts/scripts/preprocess-system-contracts.ts @@ -0,0 +1,50 @@ +import { existsSync, mkdirSync, writeFileSync } from "fs"; +import path from "path"; +import { renderFile } from "template-file"; +import { glob } from "fast-glob"; +import { Command } from "commander"; + +const CONTRACTS_DIR = "contracts"; +const OUTPUT_DIR = "contracts-preprocessed"; + +const params = { + SYSTEM_CONTRACTS_OFFSET: "0x8000", +}; + +async function preprocess(testMode: boolean) { + if (testMode) { + console.log("\x1b[31mWarning: test mode for the preprocessing being used!\x1b[0m"); + params.SYSTEM_CONTRACTS_OFFSET = "0x9000"; + } + + const contracts = await glob( + [`${CONTRACTS_DIR}/**/*.sol`, `${CONTRACTS_DIR}/**/*.yul`, `${CONTRACTS_DIR}/**/*.zasm`], + { onlyFiles: true } + ); + + for (const contract of contracts) { + const preprocessed = await renderFile(contract, params); + const fileName = `${OUTPUT_DIR}/${contract.slice(CONTRACTS_DIR.length)}`; + const directory = path.dirname(fileName); + if (!existsSync(directory)) { + mkdirSync(directory, { recursive: true }); + } + writeFileSync(fileName, preprocessed); + } + + console.log("System Contracts preprocessing done!"); +} + +async function main() { + const program = new Command(); + + program.version("0.1.0").name("system contracts preprocessor").description("preprocess the system contracts"); + + program.option("--test-mode").action(async (cmd) => { + await preprocess(cmd.testMode); + }); + + await program.parseAsync(process.argv); +} + +main(); diff --git a/system-contracts/scripts/utils.ts b/system-contracts/scripts/utils.ts new file mode 100644 index 000000000..13d1b721a --- /dev/null +++ b/system-contracts/scripts/utils.ts @@ -0,0 +1,239 @@ +import * as hre from "hardhat"; + +import type { Deployer } from "@matterlabs/hardhat-zksync-deploy"; +import type { BigNumberish, BytesLike } from "ethers"; +import { BigNumber, ethers } from "ethers"; +import * as fs from "fs"; +import { hashBytecode } from "zksync-web3/build/src/utils"; +import type { YulContractDescrption, ZasmContractDescrption } from "./constants"; +import { Language, SYSTEM_CONTRACTS } from "./constants"; +import { getCompilersDir } from "hardhat/internal/util/global-dir"; +import { getZksolcUrl, saltFromUrl } from "@matterlabs/hardhat-zksync-solc"; +import path from "path"; +import { spawn as _spawn } from "child_process"; + +export interface Dependency { + name: string; + bytecodes: BytesLike[]; + address?: string; +} + +export interface DeployedDependency { + name: string; + bytecodeHashes: string[]; + address?: string; +} + +export function readYulBytecode(description: YulContractDescrption) { + const contractName = description.codeName; + const path = `contracts-preprocessed/${description.path}/artifacts/${contractName}.yul.zbin`; + return ethers.utils.hexlify(fs.readFileSync(path)); +} + +export function readZasmBytecode(description: ZasmContractDescrption) { + const contractName = description.codeName; + const path = `contracts-preprocessed/${description.path}/artifacts/${contractName}.zasm.zbin`; + return ethers.utils.hexlify(fs.readFileSync(path)); +} + +// The struct used to represent the parameters of a forced deployment -- a deployment during upgrade +// which sets a bytecode onto an address. Typically used for updating system contracts. +export interface ForceDeployment { + // The bytecode hash to put on an address + bytecodeHash: BytesLike; + // The address on which to deploy the bytecodehash to + newAddress: string; + // Whether to call the constructor + callConstructor: boolean; + // The value with which to initialize a contract + value: BigNumberish; + // The constructor calldata + input: BytesLike; +} + +export async function outputSystemContracts(): Promise { + const upgradeParamsPromises: Promise[] = Object.values(SYSTEM_CONTRACTS).map( + async (systemContractInfo) => { + let bytecode: string; + + if (systemContractInfo.lang === Language.Yul) { + bytecode = readYulBytecode(systemContractInfo); + } else { + bytecode = (await hre.artifacts.readArtifact(systemContractInfo.codeName)).bytecode; + } + const bytecodeHash = hashBytecode(bytecode); + + return { + bytecodeHash: ethers.utils.hexlify(bytecodeHash), + newAddress: systemContractInfo.address, + value: "0", + input: "0x", + callConstructor: false, + }; + } + ); + + return await Promise.all(upgradeParamsPromises); +} + +// Script that publishes preimages for all the system contracts on zkSync +// and outputs the JSON that can be used for performing the necessary upgrade +const DEFAULT_L2_TX_GAS_LIMIT = 2097152; + +// For the given dependencies, returns an array of tuples (bytecodeHash, marker), where +// for each dependency the bytecodeHash is its versioned hash and marker is whether +// the hash has been published before. +export async function getMarkers(dependencies: BytesLike[], deployer: Deployer): Promise<[string, boolean][]> { + const contract = new ethers.Contract( + SYSTEM_CONTRACTS.knownCodesStorage.address, + (await hre.artifacts.readArtifact("KnownCodesStorage")).abi, + deployer.zkWallet + ); + + const promises = dependencies.map(async (dep) => { + const hash = ethers.utils.hexlify(hashBytecode(dep)); + const marker = BigNumber.from(await contract.getMarker(hash)); + + return [hash, marker.eq(1)] as [string, boolean]; + }); + + return await Promise.all(promises); +} + +// Checks whether the marker has been set correctly in the KnownCodesStorage +// system contract +export async function checkMarkers(dependencies: BytesLike[], deployer: Deployer) { + const markers = await getMarkers(dependencies, deployer); + + for (const [bytecodeHash, marker] of markers) { + if (!marker) { + throw new Error(`Failed to mark ${bytecodeHash}`); + } + } +} + +export function totalBytesLength(dependencies: BytesLike[]): number { + return dependencies.reduce((prev, curr) => prev + ethers.utils.arrayify(curr).length, 0); +} + +export function getBytecodes(dependencies: Dependency[]): BytesLike[] { + return dependencies.map((dep) => dep.bytecodes).flat(); +} + +export async function publishFactoryDeps( + dependencies: Dependency[], + deployer: Deployer, + nonce: number, + gasPrice: BigNumber +) { + if (dependencies.length === 0) { + throw new Error("The dependencies must be non-empty"); + } + + const bytecodes = getBytecodes(dependencies); + const combinedLength = totalBytesLength(bytecodes); + + console.log( + `\nPublishing dependencies for contracts ${dependencies + .map((dep) => { + return dep.name; + }) + .join(", ")}` + ); + console.log(`Combined length ${combinedLength}`); + + const txHandle = await deployer.zkWallet.requestExecute({ + contractAddress: ethers.constants.AddressZero, + calldata: "0x", + l2GasLimit: DEFAULT_L2_TX_GAS_LIMIT, + factoryDeps: bytecodes, + overrides: { + nonce, + gasPrice, + gasLimit: 3000000, + }, + }); + + console.log(`Transaction hash: ${txHandle.hash}`); + + console.log("Waiting for transaction commit on L1"); + + await txHandle.waitL1Commit(2); + + return txHandle; +} + +// Returns an array of bytecodes that should be published along with their total length in bytes +export async function filterPublishedFactoryDeps( + contractName: string, + factoryDeps: string[], + deployer: Deployer +): Promise<[string[], number]> { + console.log(`\nFactory dependencies for contract ${contractName}:`); + let currentLength = 0; + + const bytecodesToDeploy: string[] = []; + + const hashesAndMarkers = await getMarkers(factoryDeps, deployer); + + for (let i = 0; i < factoryDeps.length; i++) { + const depLength = ethers.utils.arrayify(factoryDeps[i]).length; + const [hash, marker] = hashesAndMarkers[i]; + console.log(`${hash} (length: ${depLength} bytes) (deployed: ${marker})`); + + if (!marker) { + currentLength += depLength; + bytecodesToDeploy.push(factoryDeps[i]); + } + } + + console.log(`Combined length to deploy: ${currentLength}`); + + return [bytecodesToDeploy, currentLength]; +} + +export async function compilerLocation(compilerVersion: string, isCompilerPreRelease: boolean): Promise { + const compilersCache = await getCompilersDir(); + + let salt = ""; + + if (isCompilerPreRelease) { + const url = getZksolcUrl("https://github.com/matter-labs/zksolc-prerelease", hre.config.zksolc.version); + salt = saltFromUrl(url); + } + + return path.join(compilersCache, "zksolc", `zksolc-v${compilerVersion}${salt ? "-" : ""}${salt}`); +} + +// executes a command in a new shell +// but pipes data to parent's stdout/stderr +export function spawn(command: string) { + command = command.replace(/\n/g, " "); + const child = _spawn(command, { stdio: "inherit", shell: true }); + return new Promise((resolve, reject) => { + child.on("error", reject); + child.on("close", (code) => { + code == 0 ? resolve(code) : reject(`Child process exited with code ${code}`); + }); + }); +} + +export class CompilerPaths { + public absolutePathSources: string; + public absolutePathArtifacts: string; + constructor(absolutePathSources: string, absolutePathArtifacts: string) { + this.absolutePathSources = absolutePathSources; + this.absolutePathArtifacts = absolutePathArtifacts; + } +} + +export function prepareCompilerPaths(path: string): CompilerPaths { + const currentWorkingDirectory = process.cwd(); + console.log(`Yarn project directory: ${currentWorkingDirectory}`); + + // This script is located in `system-contracts/scripts`, so we get one directory back. + const absolutePathSources = `${__dirname}/../${path}`; + const absolutePathArtifacts = `${__dirname}/../${path}/artifacts`; + + return new CompilerPaths(absolutePathSources, absolutePathArtifacts); +} diff --git a/system-contracts/test/AccountCodeStorage.spec.ts b/system-contracts/test/AccountCodeStorage.spec.ts new file mode 100644 index 000000000..c7d46ef96 --- /dev/null +++ b/system-contracts/test/AccountCodeStorage.spec.ts @@ -0,0 +1,238 @@ +import { expect } from "chai"; +import { ethers, network } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import type { AccountCodeStorage } from "../typechain"; +import { AccountCodeStorageFactory } from "../typechain"; +import { + EMPTY_STRING_KECCAK, + ONE_BYTES32_HEX, + TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, +} from "./shared/constants"; +import { prepareEnvironment, setResult } from "./shared/mocks"; +import { deployContractOnAddress, getWallets } from "./shared/utils"; + +describe("AccountCodeStorage tests", function () { + let wallet: Wallet; + let deployerAccount: ethers.Signer; + + let accountCodeStorage: AccountCodeStorage; + + const CONSTRUCTING_BYTECODE_HASH = "0x0101FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; + const CONSTRUCTED_BYTECODE_HASH = "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; + const RANDOM_ADDRESS = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + + before(async () => { + await prepareEnvironment(); + + wallet = getWallets()[0]; + + await deployContractOnAddress(TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, "AccountCodeStorage"); + accountCodeStorage = AccountCodeStorageFactory.connect(TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, wallet); + + deployerAccount = await ethers.getImpersonatedSigner(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + }); + + after(async () => { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS], + }); + }); + + describe("storeAccountConstructingCodeHash", function () { + it("non-deployer failed to call", async () => { + await expect( + accountCodeStorage.storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) + ).to.be.revertedWith("Callable only by the deployer system contract"); + }); + + it("failed to set with constructed bytecode", async () => { + await expect( + accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH) + ).to.be.revertedWith("Code hash is not for a contract on constructor"); + }); + + it("successfully stored", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH); + + expect(await accountCodeStorage.getRawCodeHash(RANDOM_ADDRESS)).to.be.eq( + CONSTRUCTING_BYTECODE_HASH.toLowerCase() + ); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + }); + + describe("storeAccountConstructedCodeHash", function () { + it("non-deployer failed to call", async () => { + await expect( + accountCodeStorage.storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) + ).to.be.revertedWith("Callable only by the deployer system contract"); + }); + + it("failed to set with constructing bytecode", async () => { + await expect( + accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) + ).to.be.revertedWith("Code hash is not for a constructed contract"); + }); + + it("successfully stored", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH); + + expect(await accountCodeStorage.getRawCodeHash(RANDOM_ADDRESS)).to.be.eq(CONSTRUCTED_BYTECODE_HASH.toLowerCase()); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + }); + + describe("markAccountCodeHashAsConstructed", function () { + it("non-deployer failed to call", async () => { + await expect(accountCodeStorage.markAccountCodeHashAsConstructed(RANDOM_ADDRESS)).to.be.revertedWith( + "Callable only by the deployer system contract" + ); + }); + + it("failed to mark already constructed bytecode", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH); + + await expect( + accountCodeStorage.connect(deployerAccount).markAccountCodeHashAsConstructed(RANDOM_ADDRESS) + ).to.be.revertedWith("Code hash is not for a contract on constructor"); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + + it("successfully marked", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH); + + await accountCodeStorage.connect(deployerAccount).markAccountCodeHashAsConstructed(RANDOM_ADDRESS); + + expect(await accountCodeStorage.getRawCodeHash(RANDOM_ADDRESS)).to.be.eq(CONSTRUCTED_BYTECODE_HASH.toLowerCase()); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + }); + + describe("getRawCodeHash", function () { + it("zero", async () => { + expect(await accountCodeStorage.getRawCodeHash(RANDOM_ADDRESS)).to.be.eq(ethers.constants.HashZero); + }); + + it("non-zero", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH); + + expect(await accountCodeStorage.getRawCodeHash(RANDOM_ADDRESS)).to.be.eq(CONSTRUCTED_BYTECODE_HASH.toLowerCase()); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + }); + + describe("getCodeHash", function () { + it("precompile min address", async () => { + // Check that the smallest precompile has EMPTY_STRING_KECCAK hash + expect(await accountCodeStorage.getCodeHash("0x0000000000000000000000000000000000000001")).to.be.eq( + EMPTY_STRING_KECCAK + ); + }); + + it("precompile max address", async () => { + // Check that the upper end of the precompile range has EMPTY_STRING_KECCAK hash + expect(await accountCodeStorage.getCodeHash("0x00000000000000000000000000000000000000ff")).to.be.eq( + EMPTY_STRING_KECCAK + ); + }); + + it("EOA with non-zero nonce", async () => { + await setResult("NonceHolder", "getRawNonce", [RANDOM_ADDRESS], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + expect(await accountCodeStorage.getCodeHash(RANDOM_ADDRESS)).to.be.eq(EMPTY_STRING_KECCAK); + }); + + it("address in the constructor", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH); + + expect(await accountCodeStorage.getCodeHash(RANDOM_ADDRESS)).to.be.eq(EMPTY_STRING_KECCAK); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + + it("constructed code hash", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH); + + expect(await accountCodeStorage.getCodeHash(RANDOM_ADDRESS)).to.be.eq(CONSTRUCTED_BYTECODE_HASH.toLowerCase()); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + + it("zero", async () => { + await setResult("NonceHolder", "getRawNonce", [RANDOM_ADDRESS], { + failure: false, + returnData: ethers.constants.HashZero, + }); + expect(await accountCodeStorage.getCodeHash(RANDOM_ADDRESS)).to.be.eq(ethers.constants.HashZero); + }); + }); + + describe("getCodeSize", function () { + it("zero address", async () => { + expect(await accountCodeStorage.getCodeSize(ethers.constants.AddressZero)).to.be.eq(0); + }); + + it("precompile", async () => { + expect(await accountCodeStorage.getCodeSize("0x0000000000000000000000000000000000000001")).to.be.eq(0); + }); + + it("address in the constructor", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH); + + expect(await accountCodeStorage.getCodeSize(RANDOM_ADDRESS)).to.be.eq(0); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + + it("non-zero size", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH); + + expect(await accountCodeStorage.getCodeSize(RANDOM_ADDRESS)).to.be.eq(65535 * 32); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + + it("zero", async () => { + expect(await accountCodeStorage.getCodeSize(RANDOM_ADDRESS)).to.be.eq(0); + }); + }); +}); + +// Utility function to unset code hash for the specified address. +// Deployer system contract should be impersonated +async function unsetCodeHash(accountCodeStorage: AccountCodeStorage, address: string) { + const deployerAccount = await ethers.getImpersonatedSigner(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + + await accountCodeStorage.connect(deployerAccount).storeAccountConstructedCodeHash(address, ethers.constants.HashZero); +} diff --git a/system-contracts/test/BootloaderUtilities.spec.ts b/system-contracts/test/BootloaderUtilities.spec.ts new file mode 100644 index 000000000..0178fc9cf --- /dev/null +++ b/system-contracts/test/BootloaderUtilities.spec.ts @@ -0,0 +1,185 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import * as zksync from "zksync-web3"; +import { serialize } from "zksync-web3/build/src/utils"; +import type { BootloaderUtilities } from "../typechain"; +import { BootloaderUtilitiesFactory } from "../typechain"; +import { TEST_BOOTLOADER_UTILITIES_ADDRESS } from "./shared/constants"; +import { signedTxToTransactionData } from "./shared/transactions"; +import { deployContractOnAddress, getWallets } from "./shared/utils"; + +describe("BootloaderUtilities tests", function () { + let wallet: Wallet; + let bootloaderUtilities: BootloaderUtilities; + + before(async () => { + wallet = getWallets()[0]; + await deployContractOnAddress(TEST_BOOTLOADER_UTILITIES_ADDRESS, "BootloaderUtilities"); + bootloaderUtilities = BootloaderUtilitiesFactory.connect(TEST_BOOTLOADER_UTILITIES_ADDRESS, wallet); + }); + + describe("EIP-712 transaction", function () { + it("check hashes", async () => { + const eip712Tx = await wallet.populateTransaction({ + type: 113, + to: wallet.address, + from: wallet.address, + data: "0x", + value: 0, + maxFeePerGas: 12000, + maxPriorityFeePerGas: 100, + customData: { + gasPerPubdata: zksync.utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + }, + }); + const signedEip712Tx = await wallet.signTransaction(eip712Tx); + const parsedEIP712tx = zksync.utils.parseTransaction(signedEip712Tx); + + const eip712TxData = signedTxToTransactionData(parsedEIP712tx)!; + const expectedEIP712TxHash = parsedEIP712tx.hash; + const expectedEIP712SignedHash = zksync.EIP712Signer.getSignedDigest(eip712Tx); + + const proposedEIP712Hashes = await bootloaderUtilities.getTransactionHashes(eip712TxData); + + expect(proposedEIP712Hashes.txHash).to.be.eq(expectedEIP712TxHash); + expect(proposedEIP712Hashes.signedTxHash).to.be.eq(expectedEIP712SignedHash); + }); + }); + + describe("legacy transaction", function () { + it("check hashes", async () => { + const legacyTx = await wallet.populateTransaction({ + type: 0, + to: wallet.address, + from: wallet.address, + data: "0x", + value: 0, + gasLimit: 50000, + }); + const txBytes = await wallet.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const expectedTxHash = parsedTx.hash; + delete legacyTx.from; + const expectedSignedHash = ethers.utils.keccak256(serialize(legacyTx)); + + const proposedHashes = await bootloaderUtilities.getTransactionHashes(txData); + expect(proposedHashes.txHash).to.be.eq(expectedTxHash); + expect(proposedHashes.signedTxHash).to.be.eq(expectedSignedHash); + }); + + it("invalid v signature value", async () => { + const legacyTx = await wallet.populateTransaction({ + type: 0, + to: wallet.address, + from: wallet.address, + data: "0x", + value: 0, + gasLimit: 50000, + }); + const txBytes = await wallet.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const signature = ethers.utils.arrayify(txData.signature); + signature[64] = 29; + txData.signature = signature; + + await expect(bootloaderUtilities.getTransactionHashes(txData)).to.be.revertedWith("Invalid v value"); + }); + }); + + describe("EIP-1559 transaction", function () { + it("check hashes", async () => { + const eip1559Tx = await wallet.populateTransaction({ + type: 2, + to: wallet.address, + from: wallet.address, + data: "0x", + value: 0, + maxFeePerGas: 12000, + maxPriorityFeePerGas: 100, + }); + const signedEip1559Tx = await wallet.signTransaction(eip1559Tx); + const parsedEIP1559tx = zksync.utils.parseTransaction(signedEip1559Tx); + + const EIP1559TxData = signedTxToTransactionData(parsedEIP1559tx)!; + delete eip1559Tx.from; + const expectedEIP1559TxHash = parsedEIP1559tx.hash; + const expectedEIP1559SignedHash = ethers.utils.keccak256(serialize(eip1559Tx)); + + const proposedEIP1559Hashes = await bootloaderUtilities.getTransactionHashes(EIP1559TxData); + expect(proposedEIP1559Hashes.txHash).to.be.eq(expectedEIP1559TxHash); + expect(proposedEIP1559Hashes.signedTxHash).to.be.eq(expectedEIP1559SignedHash); + }); + + it("invalid v signature value", async () => { + const eip1559Tx = await wallet.populateTransaction({ + type: 2, + to: wallet.address, + from: wallet.address, + data: "0x", + value: 0, + maxFeePerGas: 12000, + maxPriorityFeePerGas: 100, + }); + const signedEip1559Tx = await wallet.signTransaction(eip1559Tx); + const parsedEIP1559tx = zksync.utils.parseTransaction(signedEip1559Tx); + + const EIP1559TxData = signedTxToTransactionData(parsedEIP1559tx)!; + const signature = ethers.utils.arrayify(EIP1559TxData.signature); + signature[64] = 0; + EIP1559TxData.signature = signature; + + await expect(bootloaderUtilities.getTransactionHashes(EIP1559TxData)).to.be.revertedWith("Invalid v value"); + }); + }); + + describe("EIP-1559 transaction", function () { + it("check hashes", async () => { + const eip2930Tx = await wallet.populateTransaction({ + type: 1, + to: wallet.address, + from: wallet.address, + data: "0x", + value: 0, + gasLimit: 50000, + gasPrice: 55000, + }); + const signedEip2930Tx = await wallet.signTransaction(eip2930Tx); + const parsedEIP2930tx = zksync.utils.parseTransaction(signedEip2930Tx); + + const EIP2930TxData = signedTxToTransactionData(parsedEIP2930tx)!; + delete eip2930Tx.from; + const expectedEIP2930TxHash = parsedEIP2930tx.hash; + const expectedEIP2930SignedHash = ethers.utils.keccak256(serialize(eip2930Tx)); + + const proposedEIP2930Hashes = await bootloaderUtilities.getTransactionHashes(EIP2930TxData); + expect(proposedEIP2930Hashes.txHash).to.be.eq(expectedEIP2930TxHash); + expect(proposedEIP2930Hashes.signedTxHash).to.be.eq(expectedEIP2930SignedHash); + }); + + it("invalid v signature value", async () => { + const eip2930Tx = await wallet.populateTransaction({ + type: 1, + to: wallet.address, + from: wallet.address, + data: "0x", + value: 0, + gasLimit: 50000, + gasPrice: 55000, + }); + const signedEip2930Tx = await wallet.signTransaction(eip2930Tx); + const parsedEIP2930tx = zksync.utils.parseTransaction(signedEip2930Tx); + + const EIP2930TxData = signedTxToTransactionData(parsedEIP2930tx)!; + const signature = ethers.utils.arrayify(EIP2930TxData.signature); + signature[64] = 100; + EIP2930TxData.signature = signature; + + await expect(bootloaderUtilities.getTransactionHashes(EIP2930TxData)).to.be.revertedWith("Invalid v value"); + }); + }); +}); diff --git a/system-contracts/test/ComplexUpgrader.spec.ts b/system-contracts/test/ComplexUpgrader.spec.ts new file mode 100644 index 000000000..63b4a61eb --- /dev/null +++ b/system-contracts/test/ComplexUpgrader.spec.ts @@ -0,0 +1,39 @@ +import { expect } from "chai"; +import { ethers, network } from "hardhat"; +import type { ComplexUpgrader, MockContract } from "../typechain"; +import { ComplexUpgraderFactory } from "../typechain"; +import { TEST_COMPLEX_UPGRADER_CONTRACT_ADDRESS, TEST_FORCE_DEPLOYER_ADDRESS } from "./shared/constants"; +import { deployContract, deployContractOnAddress, getWallets } from "./shared/utils"; + +describe("ComplexUpgrader tests", function () { + let complexUpgrader: ComplexUpgrader; + let dummyUpgrade: MockContract; + + before(async () => { + const wallet = (await getWallets())[0]; + await deployContractOnAddress(TEST_COMPLEX_UPGRADER_CONTRACT_ADDRESS, "ComplexUpgrader"); + complexUpgrader = ComplexUpgraderFactory.connect(TEST_COMPLEX_UPGRADER_CONTRACT_ADDRESS, wallet); + dummyUpgrade = (await deployContract("MockContract")) as MockContract; + }); + + describe("upgrade", function () { + it("non force deployer failed to call", async () => { + await expect(complexUpgrader.upgrade(dummyUpgrade.address, "0xdeadbeef")).to.be.revertedWith( + "Can only be called by FORCE_DEPLOYER" + ); + }); + + it("successfully upgraded", async () => { + const force_deployer = await ethers.getImpersonatedSigner(TEST_FORCE_DEPLOYER_ADDRESS); + + await expect(complexUpgrader.connect(force_deployer).upgrade(dummyUpgrade.address, "0xdeadbeef")) + .to.emit(dummyUpgrade.attach(TEST_COMPLEX_UPGRADER_CONTRACT_ADDRESS), "Called") + .withArgs(0, "0xdeadbeef"); + + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_FORCE_DEPLOYER_ADDRESS], + }); + }); + }); +}); diff --git a/system-contracts/test/Compressor.spec.ts b/system-contracts/test/Compressor.spec.ts new file mode 100644 index 000000000..2d50ff59a --- /dev/null +++ b/system-contracts/test/Compressor.spec.ts @@ -0,0 +1,446 @@ +import { expect } from "chai"; +import type { BytesLike } from "ethers"; +import { BigNumber } from "ethers"; +import { ethers, network } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import * as zksync from "zksync-web3"; +import type { Compressor } from "../typechain"; +import { CompressorFactory } from "../typechain"; +import { + TEST_BOOTLOADER_FORMAL_ADDRESS, + TEST_COMPRESSOR_CONTRACT_ADDRESS, + TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, + TWO_IN_256, +} from "./shared/constants"; +import { encodeCalldata, getMock, prepareEnvironment, setResult } from "./shared/mocks"; +import { deployContractOnAddress, getWallets } from "./shared/utils"; + +describe("Compressor tests", function () { + let wallet: Wallet; + let bootloaderAccount: ethers.Signer; + let l1MessengerAccount: ethers.Signer; + + let compressor: Compressor; + + before(async () => { + await prepareEnvironment(); + wallet = getWallets()[0]; + + await deployContractOnAddress(TEST_COMPRESSOR_CONTRACT_ADDRESS, "Compressor"); + compressor = CompressorFactory.connect(TEST_COMPRESSOR_CONTRACT_ADDRESS, wallet); + + bootloaderAccount = await ethers.getImpersonatedSigner(TEST_BOOTLOADER_FORMAL_ADDRESS); + l1MessengerAccount = await ethers.getImpersonatedSigner(TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS); + }); + + after(async function () { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_BOOTLOADER_FORMAL_ADDRESS], + }); + + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS], + }); + }); + + describe("publishCompressedBytecode", function () { + it("non-bootloader failed to call", async () => { + await expect(compressor.publishCompressedBytecode("0x", "0x0000")).to.be.revertedWith( + "Callable only by the bootloader" + ); + }); + + it("invalid encoded length", async () => { + const BYTECODE = "0xdeadbeefdeadbeef"; + const COMPRESSED_BYTECODE = "0x0001deadbeefdeadbeef00000000"; + await expect( + compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) + ).to.be.revertedWith("Encoded data length should be 4 times shorter than the original bytecode"); + }); + + it("chunk index is out of bounds", async () => { + const BYTECODE = "0xdeadbeefdeadbeef"; + const COMPRESSED_BYTECODE = "0x0001deadbeefdeadbeef0001"; + await expect( + compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) + ).to.be.revertedWith("Encoded chunk index is out of bounds"); + }); + + it("chunk does not match the original bytecode", async () => { + const BYTECODE = "0xdeadbeefdeadbeef1111111111111111"; + const COMPRESSED_BYTECODE = "0x0002deadbeefdeadbeef111111111111111100000000"; + await expect( + compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) + ).to.be.revertedWith("Encoded chunk does not match the original bytecode"); + }); + + it("invalid bytecode length in bytes", async () => { + const BYTECODE = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + const COMPRESSED_BYTECODE = "0x0001deadbeefdeadbeef000000000000"; + await expect( + compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) + ).to.be.revertedWith("po"); + }); + + // Test case with too big bytecode is unrealistic because API cannot accept so much data. + it("invalid bytecode length in words", async () => { + const BYTECODE = "0x" + "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef".repeat(2); + const COMPRESSED_BYTECODE = "0x0001deadbeefdeadbeef" + "0000".repeat(4 * 2); + await expect( + compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) + ).to.be.revertedWith("pr"); + }); + + it("successfully published", async () => { + const BYTECODE = + "0x000200000000000200010000000103550000006001100270000000150010019d0000000101200190000000080000c13d0000000001000019004e00160000040f0000000101000039004e00160000040f0000001504000041000000150510009c000000000104801900000040011002100000000001310019000000150320009c0000000002048019000000600220021000000000012100190000004f0001042e000000000100001900000050000104300000008002000039000000400020043f0000000002000416000000000110004c000000240000613d000000000120004c0000004d0000c13d000000200100003900000100001004430000012000000443000001000100003900000040020000390000001d03000041004e000a0000040f000000000120004c0000004d0000c13d0000000001000031000000030110008c0000004d0000a13d0000000101000367000000000101043b0000001601100197000000170110009c0000004d0000c13d0000000101000039000000000101041a0000000202000039000000000202041a000000400300043d00000040043000390000001805200197000000000600041a0000000000540435000000180110019700000020043000390000000000140435000000a0012002700000001901100197000000600430003900000000001404350000001a012001980000001b010000410000000001006019000000b8022002700000001c02200197000000000121019f0000008002300039000000000012043500000018016001970000000000130435000000400100043d0000000002130049000000a0022000390000000003000019004e000a0000040f004e00140000040f0000004e000004320000004f0001042e000000500001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff000000000000000000000000000000000000000000000000000000008903573000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000ffffff0000000000008000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000007fffff00000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const COMPRESSED_BYTECODE = + "0x00510000000000000000ffffffffffffffff0000004d0000c13d00000000ffffffff0000000000140435004e000a0000040f000000000120004c00000050000104300000004f0001042e0000000101000039004e00160000040f0000000001000019000000020000000000000000007fffffffffffffff80000000000000000080000000000000ffffff8903573000000000ffffffff000000000000004e00000432004e00140000040f0000000003000019000000a0022000390000000002130049000000400100043d0000000000130435000000180160019700000000001204350000008002300039000000000121019f0000001c02200197000000b80220027000000000010060190000001b010000410000001a0120019800000060043000390000001901100197000000a001200270000000200430003900000018011001970000000000540435000000000600041a00000018052001970000004004300039000000400300043d000000000202041a0000000202000039000000000101041a000000170110009c0000001601100197000000000101043b00000001010003670000004d0000a13d000000030110008c00000000010000310000001d0300004100000040020000390000010001000039000001200000044300000100001004430000002001000039000000240000613d000000000110004c0000000002000416000000400020043f0000008002000039000000000121001900000060022002100000000002048019000000150320009c000000000131001900000040011002100000000001048019000000150510009c0000001504000041000000080000c13d0000000101200190000000150010019d0000006001100270000100000001035500020000000000020050004f004e004d004c004b000b000a0009000a004a004900480047004600450044004300420008000b000700410040003f003e003d00060002003c003b003a003900380037000500060002003600350034003300320031003000020009002f002e002d002c002b002a002900280027002600040025002400230004002200210020001f001e001d001c001b001a001900180017001600150005001400130008000700000000000000000000000000030012000000000000001100000000000000000003000100010000000000000010000f000000000000000100010001000e000000000000000d000c0000000000000000000000000000"; + await setResult("L1Messenger", "sendToL1", [COMPRESSED_BYTECODE], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await expect(compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE)) + .to.emit(getMock("KnownCodesStorage"), "Called") + .withArgs( + 0, + await encodeCalldata("KnownCodesStorage", "markBytecodeAsPublished", [zksync.utils.hashBytecode(BYTECODE)]) + ); + }); + }); + + describe("verifyCompressedStateDiffs", function () { + it("non l1 messenger failed to call", async () => { + await expect(compressor.verifyCompressedStateDiffs(0, 8, "0x", "0x0000")).to.be.revertedWith( + "Inappropriate caller" + ); + }); + + it("enumeration index size is too large", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901234", + index: 0, + initValue: BigNumber.from(0), + finalValue: BigNumber.from("0x1234567890123456789012345678901234567890123456789012345678901234"), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs[0].key = "0x1234567890123456789012345678901234567890123456789012345678901233"; + const compressedStateDiffs = compressStateDiffs(9, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 9, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("enumeration index size is too large"); + }); + + it("initial write key mismatch", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901234", + index: 0, + initValue: BigNumber.from(1), + finalValue: BigNumber.from(0), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs[0].key = "0x1234567890123456789012345678901234567890123456789012345678901233"; + const compressedStateDiffs = compressStateDiffs(4, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 4, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("iw: initial key mismatch"); + }); + + it("repeated write key mismatch", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901234", + index: 1, + initValue: BigNumber.from(1), + finalValue: BigNumber.from(0), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs[0].index = 2; + const compressedStateDiffs = compressStateDiffs(8, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 8, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("rw: enum key mismatch"); + }); + + it("no compression value mismatch", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901234", + index: 1, + initValue: BigNumber.from(1), + finalValue: BigNumber.from(0), + }, + { + key: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", + index: 0, + initValue: TWO_IN_256.div(2), + finalValue: TWO_IN_256.sub(2), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs[1].finalValue = TWO_IN_256.sub(1); + const compressedStateDiffs = compressStateDiffs(3, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 3, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("transform or no compression: compressed and final mismatch"); + }); + + it("transform value mismatch", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901234", + index: 255, + initValue: BigNumber.from(1), + finalValue: BigNumber.from(0), + }, + { + key: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", + index: 0, + initValue: TWO_IN_256.div(2), + finalValue: BigNumber.from(1), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs[1].finalValue = BigNumber.from(0); + const compressedStateDiffs = compressStateDiffs(1, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("transform or no compression: compressed and final mismatch"); + }); + + it("add value mismatch", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901235", + index: 255, + initValue: TWO_IN_256.div(2).sub(2), + finalValue: TWO_IN_256.div(2).sub(1), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs[0].finalValue = TWO_IN_256.div(2); + const compressedStateDiffs = compressStateDiffs(1, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("add: initial plus converted not equal to final"); + }); + + it("sub value mismatch", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901236", + index: 0, + initValue: TWO_IN_256.div(4), + finalValue: TWO_IN_256.div(4).sub(5), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs[0].finalValue = TWO_IN_256.div(4).sub(1); + const compressedStateDiffs = compressStateDiffs(1, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("sub: initial minus converted not equal to final"); + }); + + it("invalid operation", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901236", + index: 0, + initValue: TWO_IN_256.div(4), + finalValue: TWO_IN_256.div(4).sub(5), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + let compressedStateDiffs = compressStateDiffs(1, stateDiffs); + const compressedStateDiffsCharArray = compressedStateDiffs.split(""); + compressedStateDiffsCharArray[2 + 4 + 64 + 1] = "f"; + compressedStateDiffs = compressedStateDiffsCharArray.join(""); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("unsupported operation"); + }); + + it("Incorrect number of initial storage diffs", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901236", + index: 0, + initValue: TWO_IN_256.div(4), + finalValue: TWO_IN_256.div(4).sub(5), + }, + { + key: "0x1234567890123456789012345678901234567890123456789012345678901239", + index: 121, + initValue: TWO_IN_256.sub(1), + finalValue: BigNumber.from(0), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs.push({ + key: "0x0234567890123456789012345678901234567890123456789012345678901231", + index: 0, + initValue: BigNumber.from(0), + finalValue: BigNumber.from(1), + }); + const compressedStateDiffs = compressStateDiffs(1, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("Incorrect number of initial storage diffs"); + }); + + it("Extra data in compressed state diffs", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901236", + index: 0, + initValue: TWO_IN_256.div(4), + finalValue: TWO_IN_256.div(4).sub(5), + }, + { + key: "0x1234567890123456789012345678901234567890123456789012345678901239", + index: 121, + initValue: TWO_IN_256.sub(1), + finalValue: BigNumber.from(0), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + stateDiffs.push({ + key: "0x0234567890123456789012345678901234567890123456789012345678901231", + index: 1, + initValue: BigNumber.from(0), + finalValue: BigNumber.from(1), + }); + const compressedStateDiffs = compressStateDiffs(1, stateDiffs); + await expect( + compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) + ).to.be.revertedWith("Extra data in _compressedStateDiffs"); + }); + + it("successfully verified", async () => { + const stateDiffs = [ + { + key: "0x1234567890123456789012345678901234567890123456789012345678901230", + index: 0, + initValue: BigNumber.from("0x1234567890123456789012345678901234567890123456789012345678901231"), + finalValue: BigNumber.from("0x1234567890123456789012345678901234567890123456789012345678901230"), + }, + { + key: "0x1234567890123456789012345678901234567890123456789012345678901232", + index: 1, + initValue: TWO_IN_256.sub(1), + finalValue: BigNumber.from(1), + }, + { + key: "0x1234567890123456789012345678901234567890123456789012345678901234", + index: 0, + initValue: TWO_IN_256.div(2), + finalValue: BigNumber.from(1), + }, + { + key: "0x1234567890123456789012345678901234567890123456789012345678901236", + index: 2323, + initValue: BigNumber.from("0x1234567890123456789012345678901234567890123456789012345678901237"), + finalValue: BigNumber.from("0x0239329298382323782378478237842378478237847237237872373272373272"), + }, + { + key: "0x1234567890123456789012345678901234567890123456789012345678901238", + index: 2, + initValue: BigNumber.from(0), + finalValue: BigNumber.from(1), + }, + ]; + const encodedStateDiffs = encodeStateDiffs(stateDiffs); + const compressedStateDiffs = compressStateDiffs(4, stateDiffs); + const tx = { + from: TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, + to: compressor.address, + data: compressor.interface.encodeFunctionData("verifyCompressedStateDiffs", [ + 5, + 4, + encodedStateDiffs, + compressedStateDiffs, + ]), + }; + // eth_call to get return data + expect(await ethers.provider.call(tx)).to.be.eq(ethers.utils.keccak256(encodedStateDiffs)); + }); + }); +}); + +interface StateDiff { + key: BytesLike; + index: number; + initValue: BigNumber; + finalValue: BigNumber; +} + +function encodeStateDiffs(stateDiffs: StateDiff[]): string { + const rawStateDiffs = []; + for (const stateDiff of stateDiffs) { + rawStateDiffs.push( + ethers.utils.solidityPack( + ["address", "bytes32", "bytes32", "uint64", "uint256", "uint256", "bytes"], + [ + ethers.constants.AddressZero, + ethers.constants.HashZero, + stateDiff.key, + stateDiff.index, + stateDiff.initValue, + stateDiff.finalValue, + "0x" + "00".repeat(116), + ] + ) + ); + } + return ethers.utils.hexlify(ethers.utils.concat(rawStateDiffs)); +} + +function compressStateDiffs(enumerationIndexSize: number, stateDiffs: StateDiff[]): string { + let num_initial = 0; + const initial = []; + const repeated = []; + for (const stateDiff of stateDiffs) { + const addition = stateDiff.finalValue.sub(stateDiff.initValue).add(TWO_IN_256).mod(TWO_IN_256); + const subtraction = stateDiff.initValue.sub(stateDiff.finalValue).add(TWO_IN_256).mod(TWO_IN_256); + let op = 3; + let min = stateDiff.finalValue; + if (addition.lt(min)) { + min = addition; + op = 1; + } + if (subtraction.lt(min)) { + min = subtraction; + op = 2; + } + if (min.gte(BigNumber.from(2).pow(248))) { + min = stateDiff.finalValue; + op = 0; + } + let len = 0; + const minHex = min.eq(0) ? "0x" : min.toHexString(); + if (op > 0) { + len = (minHex.length - 2) / 2; + } + const metadata = (len << 3) + op; + const enumerationIndexType = "uint" + (enumerationIndexSize * 8).toString(); + if (stateDiff.index === 0) { + num_initial += 1; + initial.push(ethers.utils.solidityPack(["bytes32", "uint8", "bytes"], [stateDiff.key, metadata, minHex])); + } else { + repeated.push( + ethers.utils.solidityPack([enumerationIndexType, "uint8", "bytes"], [stateDiff.index, metadata, minHex]) + ); + } + } + return ethers.utils.hexlify( + ethers.utils.concat([ethers.utils.solidityPack(["uint16"], [num_initial]), ...initial, ...repeated]) + ); +} diff --git a/system-contracts/test/ContractDeployer.spec.ts b/system-contracts/test/ContractDeployer.spec.ts new file mode 100644 index 000000000..b509b7d3b --- /dev/null +++ b/system-contracts/test/ContractDeployer.spec.ts @@ -0,0 +1,681 @@ +import type { ZkSyncArtifact } from "@matterlabs/hardhat-zksync-deploy/dist/types"; +import { expect } from "chai"; +import { ethers, network } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import { utils } from "zksync-web3"; +import type { ContractDeployer } from "../typechain"; +import { ContractDeployerFactory, DeployableFactory } from "../typechain"; +import { + ONE_BYTES32_HEX, + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, + TEST_FORCE_DEPLOYER_ADDRESS, +} from "./shared/constants"; +import { prepareEnvironment, setResult } from "./shared/mocks"; +import { + deployContract, + deployContractOnAddress, + getWallets, + loadArtifact, + publishBytecode, + setConstructingCodeHash, +} from "./shared/utils"; + +describe("ContractDeployer tests", function () { + let wallet: Wallet; + let deployerAccount: ethers.Signer; + let forceDeployer: ethers.Signer; + + let contractDeployer: ContractDeployer; + let contractDeployerSystemCall: ContractDeployer; + + let deployableArtifact: ZkSyncArtifact; + + const RANDOM_ADDRESS = ethers.utils.getAddress("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + const RANDOM_ADDRESS_2 = ethers.utils.getAddress("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbee2"); + const RANDOM_ADDRESS_3 = ethers.utils.getAddress("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbee3"); + const EMPTY_KERNEL_ADDRESS = ethers.utils.getAddress("0x0000000000000000000000000000000000000101"); + const AA_VERSION_NONE = 0; + const AA_VERSION_1 = 1; + const NONCE_ORDERING_SEQUENTIAL = 0; + const NONCE_ORDERING_ARBITRARY = 1; + + before(async () => { + await prepareEnvironment(); + wallet = getWallets()[0]; + + await deployContractOnAddress(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, "ContractDeployer"); + contractDeployer = ContractDeployerFactory.connect(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, wallet); + + const contractDeployerSystemCallContract = await deployContract("SystemCaller", [contractDeployer.address]); + contractDeployerSystemCall = ContractDeployerFactory.connect(contractDeployerSystemCallContract.address, wallet); + + deployableArtifact = await loadArtifact("Deployable"); + + deployerAccount = await ethers.getImpersonatedSigner(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + forceDeployer = await ethers.getImpersonatedSigner(TEST_FORCE_DEPLOYER_ADDRESS); + }); + + after(async () => { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS], + }); + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_FORCE_DEPLOYER_ADDRESS], + }); + }); + + describe("updateAccountVersion", function () { + it("non system call failed", async () => { + await expect(contractDeployer.updateAccountVersion(AA_VERSION_NONE)).to.be.revertedWith( + "This method require system call flag" + ); + }); + + it("from none to version1", async () => { + expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).supportedAAVersion).to.be.eq( + AA_VERSION_NONE + ); + await contractDeployerSystemCall.updateAccountVersion(AA_VERSION_1); + expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).supportedAAVersion).to.be.eq( + AA_VERSION_1 + ); + }); + + it("from version1 to none", async () => { + expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).supportedAAVersion).to.be.eq( + AA_VERSION_1 + ); + await contractDeployerSystemCall.updateAccountVersion(AA_VERSION_NONE); + expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).supportedAAVersion).to.be.eq( + AA_VERSION_NONE + ); + }); + }); + + describe("updateNonceOrdering", function () { + it("non system call failed", async () => { + await expect(contractDeployer.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWith( + "This method require system call flag" + ); + }); + + it("success from sequential to arbitrary", async () => { + expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).nonceOrdering).to.be.eq( + NONCE_ORDERING_SEQUENTIAL + ); + await contractDeployerSystemCall.updateNonceOrdering(NONCE_ORDERING_ARBITRARY); + expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).nonceOrdering).to.be.eq( + NONCE_ORDERING_ARBITRARY + ); + }); + + it("failed from arbitrary to sequential", async () => { + expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).nonceOrdering).to.be.eq( + NONCE_ORDERING_ARBITRARY + ); + await expect(contractDeployerSystemCall.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWith( + "It is only possible to change from sequential to arbitrary ordering" + ); + }); + }); + + describe("getAccountInfo", function () { + it("success", async () => { + const accountInfo = await contractDeployer.getAccountInfo(RANDOM_ADDRESS); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + }); + + describe("extendedAccountVersion", function () { + it("account abstraction contract", async () => { + await contractDeployerSystemCall.updateAccountVersion(AA_VERSION_1); + expect(await contractDeployer.extendedAccountVersion(contractDeployerSystemCall.address)).to.be.eq(AA_VERSION_1); + await contractDeployerSystemCall.updateAccountVersion(AA_VERSION_NONE); + }); + + it("EOA", async () => { + await setResult("AccountCodeStorage", "getRawCodeHash", [RANDOM_ADDRESS], { + failure: false, + returnData: ethers.constants.HashZero, + }); + expect(await contractDeployer.extendedAccountVersion(RANDOM_ADDRESS)).to.be.eq(AA_VERSION_1); + }); + + it("Empty address", async () => { + await setResult("AccountCodeStorage", "getRawCodeHash", [EMPTY_KERNEL_ADDRESS], { + failure: false, + returnData: ethers.constants.HashZero, + }); + // Now testing that the system contracts with empty bytecode are still treated as AA_VERSION_NONE + expect(await contractDeployer.extendedAccountVersion(EMPTY_KERNEL_ADDRESS)).to.be.eq(AA_VERSION_NONE); + }); + + it("not AA", async () => { + await setResult("AccountCodeStorage", "getRawCodeHash", [RANDOM_ADDRESS], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + expect(await contractDeployer.extendedAccountVersion(RANDOM_ADDRESS)).to.be.eq(AA_VERSION_NONE); + }); + }); + + describe("getNewAddressCreate2", function () { + it("success", async () => { + expect( + await contractDeployer.getNewAddressCreate2( + RANDOM_ADDRESS, + "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "0x0000000022000000000123812381283812831823812838912389128938912893", + "0x" + ) + ).to.be.eq( + utils.create2Address( + RANDOM_ADDRESS, + "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "0x0000000022000000000123812381283812831823812838912389128938912893", + "0x" + ) + ); + }); + }); + + describe("getNewAddressCreate", function () { + it("success", async () => { + expect(await contractDeployer.getNewAddressCreate(RANDOM_ADDRESS, 3223233)).to.be.eq( + utils.createAddress(RANDOM_ADDRESS, 3223233) + ); + }); + }); + + // TODO: some other things can be tested: + // - check other contracts (like known codes storage) + // - cases with the kernel space address (not possible in production) + // - twice on the same address for create (not possible in production) + // - constructor behavior (failed, invalid immutables array) + // - more cases for force deployments + describe("createAccount", function () { + let expectedAddress: string; + + before(async () => { + await setResult("NonceHolder", "incrementDeploymentNonce", [contractDeployerSystemCall.address], { + failure: false, + returnData: "0x00000000000000000000000000000000000000000000000000000000deadbeef", + }); + + expectedAddress = utils.createAddress(contractDeployerSystemCall.address, "0xdeadbeef"); + await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("NonceHolder", "getRawNonce", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + + await setResult("KnownCodesStorage", "getMarker", [utils.hashBytecode(deployableArtifact.bytecode)], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + + // We still need to set in the real account code storage to make VM decommitment work. + await publishBytecode(deployableArtifact.bytecode); + await setConstructingCodeHash(expectedAddress, deployableArtifact.bytecode); + }); + + it("non system call failed", async () => { + await expect( + contractDeployer.createAccount( + ethers.constants.HashZero, + utils.hashBytecode(deployableArtifact.bytecode), + "0x", + AA_VERSION_NONE + ) + ).to.be.revertedWith("This method require system call flag"); + }); + + it("zero bytecode hash failed", async () => { + await expect( + contractDeployerSystemCall.createAccount( + ethers.constants.HashZero, + ethers.constants.HashZero, + "0x", + AA_VERSION_NONE + ) + ).to.be.revertedWith("BytecodeHash cannot be zero"); + }); + + it("not known bytecode hash failed", async () => { + await setResult( + "KnownCodesStorage", + "getMarker", + ["0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"], + { failure: false, returnData: ethers.constants.HashZero } + ); + await expect( + contractDeployerSystemCall.createAccount( + ethers.constants.HashZero, + "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "0x", + AA_VERSION_NONE + ) + ).to.be.revertedWith("The code hash is not known"); + }); + + // TODO: other mock events can be checked as well + it("successfully deployed", async () => { + await expect( + contractDeployerSystemCall.createAccount( + ethers.constants.HashZero, + utils.hashBytecode(deployableArtifact.bytecode), + "0xdeadbeef", + AA_VERSION_NONE + ) + ) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(contractDeployerSystemCall.address, utils.hashBytecode(deployableArtifact.bytecode), expectedAddress) + .to.emit(DeployableFactory.connect(expectedAddress, wallet), "Deployed") + .withArgs(0, "0xdeadbeef"); + const accountInfo = await contractDeployer.getAccountInfo(expectedAddress); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + + it("non-zero value deployed", async () => { + await expect( + contractDeployerSystemCall.createAccount( + ethers.constants.HashZero, + utils.hashBytecode(deployableArtifact.bytecode), + "0x", + AA_VERSION_NONE, + { value: 11111111 } + ) + ) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(contractDeployerSystemCall.address, utils.hashBytecode(deployableArtifact.bytecode), expectedAddress) + .to.emit(DeployableFactory.connect(expectedAddress, wallet), "Deployed") + .withArgs(11111111, "0x"); + const accountInfo = await contractDeployer.getAccountInfo(expectedAddress); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + }); + + describe("create2Account", function () { + let expectedAddress: string; + + before(async () => { + await setResult("NonceHolder", "incrementDeploymentNonce", [contractDeployerSystemCall.address], { + failure: false, + returnData: "0x00000000000000000000000000000000000000000000000000000000deadbee1", + }); + + expectedAddress = utils.create2Address( + contractDeployerSystemCall.address, + utils.hashBytecode(deployableArtifact.bytecode), + "0x1234567891234567891234512222122167891123456789123456787654323456", + "0xdeadbeef" + ); + await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("NonceHolder", "getRawNonce", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("KnownCodesStorage", "getMarker", [utils.hashBytecode(deployableArtifact.bytecode)], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + + // We still need to set in the real account code storage to make VM decommitment work. + await publishBytecode(deployableArtifact.bytecode); + await setConstructingCodeHash(expectedAddress, deployableArtifact.bytecode); + }); + + it("non system call failed", async () => { + await expect( + contractDeployer.create2Account( + "0x1234567891234567891234512222122167891123456789123456787654323456", + utils.hashBytecode(deployableArtifact.bytecode), + "0xdeadbeef", + AA_VERSION_NONE + ) + ).to.be.revertedWith("This method require system call flag"); + }); + + it("zero bytecode hash failed", async () => { + await expect( + contractDeployerSystemCall.create2Account( + "0x1234567891234567891234512222122167891123456789123456787654323456", + ethers.constants.HashZero, + "0x", + AA_VERSION_NONE + ) + ).to.be.revertedWith("BytecodeHash cannot be zero"); + }); + + it("not known bytecode hash failed", async () => { + const expectedAddress = utils.create2Address( + contractDeployerSystemCall.address, + "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "0x1234567891234567891234512222122167891123456789123456787654323456", + "0x" + ); + await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("NonceHolder", "getRawNonce", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult( + "KnownCodesStorage", + "getMarker", + ["0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"], + { failure: false, returnData: ethers.constants.HashZero } + ); + await expect( + contractDeployerSystemCall.create2Account( + "0x1234567891234567891234512222122167891123456789123456787654323456", + "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "0x", + AA_VERSION_NONE + ) + ).to.be.revertedWith("The code hash is not known"); + }); + + it("successfully deployed", async () => { + await expect( + contractDeployerSystemCall.create2Account( + "0x1234567891234567891234512222122167891123456789123456787654323456", + utils.hashBytecode(deployableArtifact.bytecode), + "0xdeadbeef", + AA_VERSION_NONE + ) + ) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(contractDeployerSystemCall.address, utils.hashBytecode(deployableArtifact.bytecode), expectedAddress) + .to.emit(DeployableFactory.connect(expectedAddress, wallet), "Deployed") + .withArgs(0, "0xdeadbeef"); + const accountInfo = await contractDeployer.getAccountInfo(expectedAddress); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + + it("already deployed failed", async () => { + await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { + failure: false, + returnData: utils.hashBytecode(deployableArtifact.bytecode), + }); + await expect( + contractDeployerSystemCall.create2Account( + "0x1234567891234567891234512222122167891123456789123456787654323456", + utils.hashBytecode(deployableArtifact.bytecode), + "0xdeadbeef", + AA_VERSION_NONE + ) + ).to.be.revertedWith("Code hash is non-zero"); + await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + }); + + it("non-zero value deployed", async () => { + await expect( + contractDeployerSystemCall.create2Account( + "0x1234567891234567891234512222122167891123456789123456787654323456", + utils.hashBytecode(deployableArtifact.bytecode), + "0xdeadbeef", + AA_VERSION_NONE, + { value: 5555 } + ) + ) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(contractDeployerSystemCall.address, utils.hashBytecode(deployableArtifact.bytecode), expectedAddress) + .to.emit(DeployableFactory.connect(expectedAddress, wallet), "Deployed") + .withArgs(5555, "0xdeadbeef"); + const accountInfo = await contractDeployer.getAccountInfo(expectedAddress); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + }); + + describe("create", function () { + let expectedAddress; + + before(async () => { + await setResult("NonceHolder", "incrementDeploymentNonce", [contractDeployerSystemCall.address], { + failure: false, + returnData: "0x00000000000000000000000000000000000000000000000000000000deadbee2", + }); + + expectedAddress = utils.createAddress(contractDeployerSystemCall.address, "0xdeadbee2"); + await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("NonceHolder", "getRawNonce", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("KnownCodesStorage", "getMarker", [utils.hashBytecode(deployableArtifact.bytecode)], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + + // We still need to set in the real account code storage to make VM decommitment work. + await publishBytecode(deployableArtifact.bytecode); + await setConstructingCodeHash(expectedAddress, deployableArtifact.bytecode); + }); + + it("non system call failed", async () => { + await expect( + contractDeployer.create(ethers.constants.HashZero, utils.hashBytecode(deployableArtifact.bytecode), "0x") + ).to.be.revertedWith("This method require system call flag"); + }); + + it("successfully deployed", async () => { + await expect( + contractDeployerSystemCall.create( + ethers.constants.HashZero, + utils.hashBytecode(deployableArtifact.bytecode), + "0x12" + ) + ) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(contractDeployerSystemCall.address, utils.hashBytecode(deployableArtifact.bytecode), expectedAddress) + .to.emit(DeployableFactory.connect(expectedAddress, wallet), "Deployed") + .withArgs(0, "0x12"); + const accountInfo = await contractDeployer.getAccountInfo(expectedAddress); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + }); + // + describe("create2", function () { + let expectedAddress: string; + + before(async () => { + await setResult("NonceHolder", "incrementDeploymentNonce", [contractDeployerSystemCall.address], { + failure: false, + returnData: "0x00000000000000000000000000000000000000000000000000000000deadbee3", + }); + + expectedAddress = utils.create2Address( + contractDeployerSystemCall.address, + utils.hashBytecode(deployableArtifact.bytecode), + ethers.constants.HashZero, + "0xabcd" + ); + await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("NonceHolder", "getRawNonce", [expectedAddress], { + failure: false, + returnData: ethers.constants.HashZero, + }); + await setResult("KnownCodesStorage", "getMarker", [utils.hashBytecode(deployableArtifact.bytecode)], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + + // We still need to set in the real account code storage to make VM decommitment work. + await publishBytecode(deployableArtifact.bytecode); + await setConstructingCodeHash(expectedAddress, deployableArtifact.bytecode); + }); + + it("non system call failed", async () => { + await expect( + contractDeployer.create2(ethers.constants.HashZero, utils.hashBytecode(deployableArtifact.bytecode), "0xabcd") + ).to.be.revertedWith("This method require system call flag"); + }); + + it("successfully deployed", async () => { + await expect( + contractDeployerSystemCall.create2( + ethers.constants.HashZero, + utils.hashBytecode(deployableArtifact.bytecode), + "0xabcd" + ) + ) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(contractDeployerSystemCall.address, utils.hashBytecode(deployableArtifact.bytecode), expectedAddress) + .to.emit(DeployableFactory.connect(expectedAddress, wallet), "Deployed") + .withArgs(0, "0xabcd"); + const accountInfo = await contractDeployer.getAccountInfo(expectedAddress); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + }); + + describe("forceDeployOnAddress", function () { + it("not from self call failed", async () => { + const deploymentData = { + bytecodeHash: utils.hashBytecode(deployableArtifact.bytecode), + newAddress: RANDOM_ADDRESS, + callConstructor: false, + value: 0, + input: "0x", + }; + await expect(contractDeployer.forceDeployOnAddress(deploymentData, wallet.address)).to.be.revertedWith( + "Callable only by self" + ); + }); + + it("not known bytecode hash failed", async () => { + await setResult( + "KnownCodesStorage", + "getMarker", + ["0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"], + { failure: false, returnData: ethers.constants.HashZero } + ); + const deploymentData = { + bytecodeHash: "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + newAddress: RANDOM_ADDRESS, + callConstructor: false, + value: 0, + input: "0x", + }; + await expect( + contractDeployer.connect(deployerAccount).forceDeployOnAddress(deploymentData, wallet.address) + ).to.be.revertedWith("The code hash is not known"); + }); + + it("successfully deployed", async () => { + await setResult("KnownCodesStorage", "getMarker", [utils.hashBytecode(deployableArtifact.bytecode)], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + const deploymentData = { + bytecodeHash: utils.hashBytecode(deployableArtifact.bytecode), + newAddress: RANDOM_ADDRESS, + callConstructor: false, + value: 0, + input: "0x", + }; + await expect(contractDeployer.connect(deployerAccount).forceDeployOnAddress(deploymentData, wallet.address)) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(wallet.address, utils.hashBytecode(deployableArtifact.bytecode), RANDOM_ADDRESS) + .to.not.emit(DeployableFactory.connect(RANDOM_ADDRESS, wallet), "Deployed"); + const accountInfo = await contractDeployer.getAccountInfo(RANDOM_ADDRESS); + expect(accountInfo.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + }); + + describe("forceDeployOnAddresses", function () { + it("not allowed to call", async () => { + const deploymentData = [ + { + bytecodeHash: utils.hashBytecode(deployableArtifact.bytecode), + newAddress: RANDOM_ADDRESS_2, + callConstructor: true, + value: 0, + input: "0x", + }, + { + bytecodeHash: utils.hashBytecode(deployableArtifact.bytecode), + newAddress: RANDOM_ADDRESS_3, + callConstructor: false, + value: 0, + input: "0xab", + }, + ]; + await expect(contractDeployer.forceDeployOnAddresses(deploymentData)).to.be.revertedWith( + "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT" + ); + }); + + it("successfully deployed", async () => { + await setResult("KnownCodesStorage", "getMarker", [utils.hashBytecode(deployableArtifact.bytecode)], { + failure: false, + returnData: ONE_BYTES32_HEX, + }); + + // We still need to set in the real account code storage to make VM decommitment work. + await publishBytecode(deployableArtifact.bytecode); + await setConstructingCodeHash(RANDOM_ADDRESS_2, deployableArtifact.bytecode); + await setConstructingCodeHash(RANDOM_ADDRESS_3, deployableArtifact.bytecode); + + const deploymentData = [ + { + bytecodeHash: utils.hashBytecode(deployableArtifact.bytecode), + newAddress: RANDOM_ADDRESS_2, + callConstructor: true, + value: 0, + input: "0x", + }, + { + bytecodeHash: utils.hashBytecode(deployableArtifact.bytecode), + newAddress: RANDOM_ADDRESS_3, + callConstructor: false, + value: 0, + input: "0xab", + }, + ]; + await expect(contractDeployer.connect(forceDeployer).forceDeployOnAddresses(deploymentData)) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(forceDeployer.address, utils.hashBytecode(deployableArtifact.bytecode), RANDOM_ADDRESS_2) + .to.emit(contractDeployer, "ContractDeployed") + .withArgs(forceDeployer.address, utils.hashBytecode(deployableArtifact.bytecode), RANDOM_ADDRESS_3) + .to.emit(DeployableFactory.connect(RANDOM_ADDRESS_2, wallet), "Deployed") + .withArgs(0, "0x") + .to.not.emit(DeployableFactory.connect(RANDOM_ADDRESS_3, wallet), "Deployed"); + + const accountInfo1 = await contractDeployer.getAccountInfo(RANDOM_ADDRESS_2); + expect(accountInfo1.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo1.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + + const accountInfo2 = await contractDeployer.getAccountInfo(RANDOM_ADDRESS_3); + expect(accountInfo2.supportedAAVersion).to.be.eq(AA_VERSION_NONE); + expect(accountInfo2.nonceOrdering).to.be.eq(NONCE_ORDERING_SEQUENTIAL); + }); + }); +}); diff --git a/system-contracts/test/DefaultAccount.spec.ts b/system-contracts/test/DefaultAccount.spec.ts new file mode 100644 index 000000000..4aa8cd6a2 --- /dev/null +++ b/system-contracts/test/DefaultAccount.spec.ts @@ -0,0 +1,399 @@ +import { expect } from "chai"; +import { ethers, network } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import * as zksync from "zksync-web3"; +import { serialize } from "zksync-web3/build/src/utils"; +import type { DefaultAccount, DelegateCaller, MockContract } from "../typechain"; +import { DefaultAccountFactory } from "../typechain"; +import { TEST_BOOTLOADER_FORMAL_ADDRESS } from "./shared/constants"; +import { getMock } from "./shared/mocks"; +import { signedTxToTransactionData } from "./shared/transactions"; +import { deployContract, deployContractOnAddress, getWallets, loadArtifact } from "./shared/utils"; + +// TODO: more test cases can be added. +describe("DefaultAccount tests", function () { + let wallet: Wallet; + let bootloaderAccount: ethers.Signer; + + let defaultAccount: DefaultAccount; + let account: Wallet; + let callable: MockContract; + let delegateCaller: DelegateCaller; + let mockERC20: MockContract; + + let paymasterFlowIface: ethers.utils.Interface; + let ERC20Iface: ethers.utils.Interface; + + const RANDOM_ADDRESS = ethers.utils.getAddress("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + + before(async () => { + wallet = getWallets()[0]; + account = getWallets()[2]; + + await deployContractOnAddress(account.address, "DefaultAccount"); + defaultAccount = DefaultAccountFactory.connect(account.address, wallet); + + callable = (await deployContract("MockContract")) as MockContract; + delegateCaller = (await deployContract("DelegateCaller")) as DelegateCaller; + mockERC20 = (await deployContract("MockContract")) as MockContract; + + paymasterFlowIface = new ethers.utils.Interface((await loadArtifact("IPaymasterFlow")).abi); + ERC20Iface = new ethers.utils.Interface((await loadArtifact("IERC20")).abi); + + bootloaderAccount = await ethers.getImpersonatedSigner(TEST_BOOTLOADER_FORMAL_ADDRESS); + }); + + after(async function () { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_BOOTLOADER_FORMAL_ADDRESS], + }); + }); + + describe("validateTransaction", function () { + it("non-deployer ignored", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: RANDOM_ADDRESS, + from: account.address, + nonce: 1, + data: "0x", + value: 0, + gasLimit: 50000, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + const call = { + from: wallet.address, + to: defaultAccount.address, + value: 0, + data: defaultAccount.interface.encodeFunctionData("validateTransaction", [txHash, signedHash, txData]), + }; + expect(await wallet.provider.call(call)).to.be.eq("0x"); + }); + + it("invalid signature", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: RANDOM_ADDRESS, + from: account.address, + nonce: 1, + data: "0x", + value: 0, + gasLimit: 50000, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + parsedTx.s = "0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0"; + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + const call = { + from: TEST_BOOTLOADER_FORMAL_ADDRESS, + to: defaultAccount.address, + value: 0, + data: defaultAccount.interface.encodeFunctionData("validateTransaction", [txHash, signedHash, txData]), + }; + expect(await bootloaderAccount.provider.call(call)).to.be.eq(ethers.constants.HashZero); + }); + + it("valid tx", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: RANDOM_ADDRESS, + from: account.address, + nonce: 5, + data: "0x", + value: 0, + gasLimit: 50000, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + const call = { + from: TEST_BOOTLOADER_FORMAL_ADDRESS, + to: defaultAccount.address, + value: 0, + data: defaultAccount.interface.encodeFunctionData("validateTransaction", [txHash, signedHash, txData]), + }; + expect(await bootloaderAccount.provider.call(call)).to.be.eq( + defaultAccount.interface.getSighash("validateTransaction") + "0".repeat(56) + ); + }); + }); + + describe("executeTransaction", function () { + it("non-deployer ignored", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: callable.address, + from: account.address, + nonce: 111, + data: "0xdeadbeef", + value: 5, + gasLimit: 50000, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + await expect(await defaultAccount.executeTransaction(txHash, signedHash, txData)).to.not.emit(callable, "Called"); + }); + + it("successfully executed", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: callable.address, + from: account.address, + nonce: 111, + data: "0xdeadbeef", + value: 0, + gasLimit: 50000, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + await expect(await defaultAccount.connect(bootloaderAccount).executeTransaction(txHash, signedHash, txData)) + .to.emit(callable, "Called") + .withArgs(0, "0xdeadbeef"); + }); + + it("non-zero value", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: callable.address, + from: account.address, + nonce: 111, + data: "0x", + value: 5, + gasLimit: 50000, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + await expect(await defaultAccount.connect(bootloaderAccount).executeTransaction(txHash, signedHash, txData)) + .to.emit(getMock("MsgValueSimulator"), "Called") + .withArgs(0, "0x"); + }); + }); + + describe("executeTransactionFromOutside", function () { + it("nothing", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: callable.address, + from: account.address, + nonce: 111, + data: "0xdeadbeef", + value: 5, + gasLimit: 50000, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + delete legacyTx.from; + + await expect(await defaultAccount.executeTransactionFromOutside(txData)).to.not.emit(callable, "Called"); + }); + }); + + describe("payForTransaction", function () { + it("non-deployer ignored", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: callable.address, + from: account.address, + nonce: 1, + data: "0xdeadbeef", + value: 5, + gasLimit: 50000, + gasPrice: 200, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + await expect(defaultAccount.payForTransaction(txHash, signedHash, txData)).to.not.emit( + getMock("Bootloader"), + "Called" + ); + }); + + it("successfully payed", async () => { + const legacyTx = await account.populateTransaction({ + type: 0, + to: callable.address, + from: account.address, + nonce: 2, + data: "0xdeadbeef", + value: 5, + gasLimit: 50000, + gasPrice: 200, + }); + const txBytes = await account.signTransaction(legacyTx); + const parsedTx = zksync.utils.parseTransaction(txBytes); + const txData = signedTxToTransactionData(parsedTx)!; + + const txHash = parsedTx.hash; + delete legacyTx.from; + const signedHash = ethers.utils.keccak256(serialize(legacyTx)); + + await expect(await defaultAccount.connect(bootloaderAccount).payForTransaction(txHash, signedHash, txData)) + .to.emit(getMock("Bootloader"), "Called") + .withArgs(50000 * 200, "0x"); + }); + }); + + describe("prepareForPaymaster", function () { + it("non-deployer ignored", async () => { + const eip712Tx = await account.populateTransaction({ + type: 113, + to: callable.address, + from: account.address, + data: "0x", + value: 0, + maxFeePerGas: 12000, + maxPriorityFeePerGas: 100, + gasLimit: 50000, + customData: { + gasPerPubdata: zksync.utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + paymasterParams: { + paymaster: RANDOM_ADDRESS, + paymasterInput: paymasterFlowIface.encodeFunctionData("approvalBased", [mockERC20.address, 2023, "0x"]), + }, + }, + }); + const signedEip712Tx = await account.signTransaction(eip712Tx); + const parsedEIP712tx = zksync.utils.parseTransaction(signedEip712Tx); + + const eip712TxData = signedTxToTransactionData(parsedEIP712tx)!; + const eip712TxHash = parsedEIP712tx.hash; + const eip712SignedHash = zksync.EIP712Signer.getSignedDigest(eip712Tx); + + await expect(await defaultAccount.prepareForPaymaster(eip712TxHash, eip712SignedHash, eip712TxData)).to.not.emit( + mockERC20, + "Called" + ); + }); + + it("successfully prepared", async () => { + await mockERC20.setResult({ + input: ERC20Iface.encodeFunctionData("allowance", [account.address, RANDOM_ADDRESS]), + failure: false, + returnData: ethers.constants.HashZero, + }); + const eip712Tx = await account.populateTransaction({ + type: 113, + to: callable.address, + from: account.address, + data: "0x", + value: 0, + maxFeePerGas: 12000, + maxPriorityFeePerGas: 100, + gasLimit: 50000, + customData: { + gasPerPubdata: zksync.utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + paymasterParams: { + paymaster: RANDOM_ADDRESS, + paymasterInput: paymasterFlowIface.encodeFunctionData("approvalBased", [mockERC20.address, 2023, "0x"]), + }, + }, + }); + const signedEip712Tx = await account.signTransaction(eip712Tx); + const parsedEIP712tx = zksync.utils.parseTransaction(signedEip712Tx); + + const eip712TxData = signedTxToTransactionData(parsedEIP712tx)!; + const eip712TxHash = parsedEIP712tx.hash; + const eip712SignedHash = zksync.EIP712Signer.getSignedDigest(eip712Tx); + + await expect( + await defaultAccount + .connect(bootloaderAccount) + .prepareForPaymaster(eip712TxHash, eip712SignedHash, eip712TxData) + ) + .to.emit(mockERC20, "Called") + .withArgs(0, ERC20Iface.encodeFunctionData("approve", [RANDOM_ADDRESS, 2023])); + }); + }); + + describe("fallback/receive", function () { + it("zero value by EOA wallet", async () => { + const call = { + from: wallet.address, + to: defaultAccount.address, + value: 0, + data: "0x872384894899834939049043904390390493434343434344433443433434344234234234", + }; + expect(await wallet.provider.call(call)).to.be.eq("0x"); + }); + + it("non-zero value by EOA wallet", async () => { + const call = { + from: wallet.address, + to: defaultAccount.address, + value: 3223, + data: "0x87238489489983493904904390431212224343434344433443433434344234234234", + }; + expect(await wallet.provider.call(call)).to.be.eq("0x"); + }); + + it("zero value by bootloader", async () => { + // Here we need to ensure that during delegatecalls even if `msg.sender` is the bootloader, + // the fallback is behaving correctly + const calldata = delegateCaller.interface.encodeFunctionData("delegateCall", [defaultAccount.address]); + const call = { + from: TEST_BOOTLOADER_FORMAL_ADDRESS, + to: delegateCaller.address, + value: 0, + data: calldata, + }; + expect(await bootloaderAccount.call(call)).to.be.eq("0x"); + }); + + it("non-zero value by bootloader", async () => { + // Here we need to ensure that during delegatecalls even if `msg.sender` is the bootloader, + // the fallback is behaving correctly + const calldata = delegateCaller.interface.encodeFunctionData("delegateCall", [defaultAccount.address]); + const call = { + from: TEST_BOOTLOADER_FORMAL_ADDRESS, + to: delegateCaller.address, + value: 3223, + data: calldata, + }; + expect(await bootloaderAccount.call(call)).to.be.eq("0x"); + }); + }); +}); diff --git a/system-contracts/test/EmptyContract.spec.ts b/system-contracts/test/EmptyContract.spec.ts new file mode 100644 index 000000000..73966fe7e --- /dev/null +++ b/system-contracts/test/EmptyContract.spec.ts @@ -0,0 +1,44 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import type { EmptyContract } from "../typechain"; +import { deployContract, getWallets, provider } from "./shared/utils"; + +describe("EmptyContract tests", function () { + let wallet: Wallet; + let emptyContract: EmptyContract; + + before(async () => { + wallet = getWallets()[0]; + emptyContract = (await deployContract("EmptyContract")) as EmptyContract; + }); + + it("zero value", async () => { + const tx = { + from: wallet.address, + to: emptyContract.address, + value: 0, + data: "0x1234567890deadbeef1234567890", + }; + expect(await provider.call(tx)).to.be.eq("0x"); + }); + + it("non-zero value", async () => { + const tx = { + from: wallet.address, + to: emptyContract.address, + value: ethers.utils.parseEther("1.0"), + data: "0x1234567890deadbeef1234567890", + }; + expect(await provider.call(tx)).to.be.eq("0x"); + }); + + it("empty calldata", async () => { + const tx = { + from: wallet.address, + to: emptyContract.address, + data: "", + }; + expect(await provider.call(tx)).to.be.eq("0x"); + }); +}); diff --git a/system-contracts/test/EventWriter.spec.ts b/system-contracts/test/EventWriter.spec.ts new file mode 100644 index 000000000..908036963 --- /dev/null +++ b/system-contracts/test/EventWriter.spec.ts @@ -0,0 +1,188 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import { Contract } from "zksync-web3"; +import type { TransactionResponse } from "zksync-web3/build/src/types"; +import { ONE_BYTES32_HEX, REAL_EVENT_WRITER_CONTRACT_ADDRESS } from "./shared/constants"; +import { EXTRA_ABI_CALLER_ADDRESS, encodeExtraAbiCallerCalldata } from "./shared/extraAbiCaller"; +import { getCode, getWallets, loadYulBytecode, loadZasmBytecode, setCode } from "./shared/utils"; + +describe("EventWriter tests", function () { + let wallet: Wallet; + + let eventWriter: Contract; + let extraAbiCaller: Contract; + + let realEventWriterBytecode: string; + + before(async () => { + wallet = getWallets()[0]; + + realEventWriterBytecode = await getCode(REAL_EVENT_WRITER_CONTRACT_ADDRESS); + + const eventWriterBytecode = loadYulBytecode("EventWriter", ""); + await setCode(REAL_EVENT_WRITER_CONTRACT_ADDRESS, eventWriterBytecode); + eventWriter = new Contract(REAL_EVENT_WRITER_CONTRACT_ADDRESS, [], wallet); + + const extraAbiCallerBytecode = await loadZasmBytecode("ExtraAbiCaller", "test-contracts"); + await setCode(EXTRA_ABI_CALLER_ADDRESS, extraAbiCallerBytecode); + extraAbiCaller = new Contract(EXTRA_ABI_CALLER_ADDRESS, [], wallet); + }); + + after(async () => { + await setCode(REAL_EVENT_WRITER_CONTRACT_ADDRESS, realEventWriterBytecode); + }); + + it("non system call failed", async () => { + await expect(eventWriter.fallback({ data: "0x" })).to.be.reverted; + }); + + it("zero topics", async () => { + const txResponse = await extraAbiCaller.fallback({ + data: encodeExtraAbiCallerCalldata(REAL_EVENT_WRITER_CONTRACT_ADDRESS, 0, [0], "0x"), + }); + expect(await checkReturnedEvent(txResponse, extraAbiCaller.address, [], "0x")).to.be.eq(true); + }); + + it("one topic", async () => { + const txResponse = await extraAbiCaller.fallback({ + data: encodeExtraAbiCallerCalldata( + REAL_EVENT_WRITER_CONTRACT_ADDRESS, + 0, + [1, "0x1234567890123456789012345678901234567890123456789012345678901234"], + "0xdeadbeef" + ), + }); + expect( + await checkReturnedEvent( + txResponse, + extraAbiCaller.address, + ["0x1234567890123456789012345678901234567890123456789012345678901234"], + "0xdeadbeef" + ) + ).to.be.eq(true); + }); + + it("two topics", async () => { + const txResponse = await extraAbiCaller.fallback({ + data: encodeExtraAbiCallerCalldata( + REAL_EVENT_WRITER_CONTRACT_ADDRESS, + 0, + [ + 2, + "0x1234567890123456789012345678901234567890123456789012345678901234", + "0x1278378123784223232874782378478237848723784782378423747237848723", + ], + "0xabcd" + ), + }); + expect( + await checkReturnedEvent( + txResponse, + extraAbiCaller.address, + [ + "0x1234567890123456789012345678901234567890123456789012345678901234", + "0x1278378123784223232874782378478237848723784782378423747237848723", + ], + "0xabcd" + ) + ).to.be.eq(true); + }); + + it("three topics", async () => { + const txResponse = await extraAbiCaller.fallback({ + data: encodeExtraAbiCallerCalldata( + REAL_EVENT_WRITER_CONTRACT_ADDRESS, + 0, + [ + 3, + "0x1234567890123456789012345678901234567890123456789012345678901234", + "0x1278378123784223232874782378478237848723784782378423747237848723", + ethers.constants.HashZero, + ], + "0x" + ), + }); + expect( + await checkReturnedEvent( + txResponse, + extraAbiCaller.address, + [ + "0x1234567890123456789012345678901234567890123456789012345678901234", + "0x1278378123784223232874782378478237848723784782378423747237848723", + ethers.constants.HashZero, + ], + "0x" + ) + ).to.be.eq(true); + }); + + it("four topics", async () => { + const txResponse = await extraAbiCaller.fallback({ + data: encodeExtraAbiCallerCalldata( + REAL_EVENT_WRITER_CONTRACT_ADDRESS, + 0, + [ + 4, + ONE_BYTES32_HEX, + "0x1234567890123456789012345678901234567890123456789012345678901234", + "0x1278378123784223232874782378478237848723784782378423747237848723", + ethers.constants.HashZero, + ], + "0x2828383489438934898934893894893895348915893489589348958349589348958934859348958934858394589348958934854385838954893489" + ), + }); + expect( + await checkReturnedEvent( + txResponse, + extraAbiCaller.address, + [ + ONE_BYTES32_HEX, + "0x1234567890123456789012345678901234567890123456789012345678901234", + "0x1278378123784223232874782378478237848723784782378423747237848723", + ethers.constants.HashZero, + ], + "0x2828383489438934898934893894893895348915893489589348958349589348958934859348958934858394589348958934854385838954893489" + ) + ).to.be.eq(true); + }); + + it("five topics failed", async () => { + await expect( + extraAbiCaller.fallback({ + data: encodeExtraAbiCallerCalldata( + REAL_EVENT_WRITER_CONTRACT_ADDRESS, + 0, + [5, ONE_BYTES32_HEX, ONE_BYTES32_HEX, ONE_BYTES32_HEX, ONE_BYTES32_HEX, ONE_BYTES32_HEX], + "0x" + ), + }) + ).to.be.reverted; + }); +}); + +async function checkReturnedEvent( + txResponse: TransactionResponse, + address: string, + topics: string[], + data: string +): boolean { + const receipt = await txResponse.wait(); + const eventsFromAddress = receipt.logs.filter((log) => log.address.toLowerCase() === address.toLowerCase()); + if (eventsFromAddress.length !== 1) { + return false; + } + const foundEvent = eventsFromAddress[0]; + if (foundEvent.topics.length !== topics.length) { + return false; + } + for (let i = 0; i < topics.length; i++) { + if (topics[i].toLowerCase() !== foundEvent.topics[i].toLowerCase()) { + return false; + } + } + if (foundEvent.data.toLowerCase() !== data.toLowerCase()) { + return false; + } + return true; +} diff --git a/system-contracts/test/ImmutableSimulator.spec.ts b/system-contracts/test/ImmutableSimulator.spec.ts new file mode 100644 index 000000000..530fa370c --- /dev/null +++ b/system-contracts/test/ImmutableSimulator.spec.ts @@ -0,0 +1,65 @@ +import { expect } from "chai"; +import { ethers, network } from "hardhat"; +import type { ImmutableSimulator } from "../typechain"; +import { ImmutableSimulatorFactory } from "../typechain"; +import { + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, + TEST_IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT_ADDRESS, +} from "./shared/constants"; +import { deployContractOnAddress, getWallets } from "./shared/utils"; + +describe("ImmutableSimulator tests", function () { + let immutableSimulator: ImmutableSimulator; + + const RANDOM_ADDRESS = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + const IMMUTABLES_DATA = [ + { + index: 0, + value: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", + }, + { + index: 23, + value: "0x0000000000000000000000000000000000000000000000000000000000000111", + }, + ]; + + before(async () => { + const wallet = getWallets()[0]; + await deployContractOnAddress(TEST_IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT_ADDRESS, "ImmutableSimulator"); + immutableSimulator = ImmutableSimulatorFactory.connect(TEST_IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT_ADDRESS, wallet); + }); + + describe("setImmutables", function () { + it("non-deployer failed to call", async () => { + await expect(immutableSimulator.setImmutables(RANDOM_ADDRESS, IMMUTABLES_DATA)).to.be.revertedWith( + "Callable only by the deployer system contract" + ); + }); + + it("successfully set", async () => { + await network.provider.request({ + method: "hardhat_impersonateAccount", + params: [TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS], + }); + + const deployer_account = await ethers.getSigner(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + + await immutableSimulator.connect(deployer_account).setImmutables(RANDOM_ADDRESS, IMMUTABLES_DATA); + + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS], + }); + + for (const immutable of IMMUTABLES_DATA) { + expect(await immutableSimulator.getImmutable(RANDOM_ADDRESS, immutable.index)).to.be.eq(immutable.value); + } + }); + }); + + describe("getImmutable", function () { + it("zero", async () => { + expect(await immutableSimulator.getImmutable(RANDOM_ADDRESS, 333)).to.be.eq(ethers.constants.HashZero); + }); + }); +}); diff --git a/system-contracts/test/KnownCodesStorage.spec.ts b/system-contracts/test/KnownCodesStorage.spec.ts new file mode 100644 index 000000000..df1cb46be --- /dev/null +++ b/system-contracts/test/KnownCodesStorage.spec.ts @@ -0,0 +1,145 @@ +import { expect } from "chai"; +import { ethers, network } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import type { KnownCodesStorage } from "../typechain"; +import { KnownCodesStorageFactory } from "../typechain"; +import { + TEST_BOOTLOADER_FORMAL_ADDRESS, + TEST_COMPRESSOR_CONTRACT_ADDRESS, + TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, +} from "./shared/constants"; +import { encodeCalldata, getMock, prepareEnvironment } from "./shared/mocks"; +import { deployContractOnAddress, getWallets } from "./shared/utils"; + +describe("KnownCodesStorage tests", function () { + let wallet: Wallet; + let bootloaderAccount: ethers.Signer; + let compressorAccount: ethers.Signer; + + let knownCodesStorage: KnownCodesStorage; + + const BYTECODE_HASH_1 = "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; + const BYTECODE_HASH_2 = "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE1"; + const BYTECODE_HASH_3 = "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE2"; + const BYTECODE_HASH_4 = "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE3"; + const INCORRECTLY_FORMATTED_HASH = "0x0120FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; + const INVALID_LENGTH_HASH = "0x0100FFFEDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; + + // TODO: currently test depends on the previous state and can not be run twice, think about fixing it. Relevant for other tests as well. + before(async () => { + await prepareEnvironment(); + wallet = (await getWallets())[0]; + + await deployContractOnAddress(TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, "KnownCodesStorage"); + knownCodesStorage = KnownCodesStorageFactory.connect(TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, wallet); + + bootloaderAccount = await ethers.getImpersonatedSigner(TEST_BOOTLOADER_FORMAL_ADDRESS); + compressorAccount = await ethers.getImpersonatedSigner(TEST_COMPRESSOR_CONTRACT_ADDRESS); + }); + + after(async () => { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_BOOTLOADER_FORMAL_ADDRESS], + }); + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_COMPRESSOR_CONTRACT_ADDRESS], + }); + }); + + describe("markBytecodeAsPublished", function () { + it("non-compressor failed to call", async () => { + await expect(knownCodesStorage.markBytecodeAsPublished(BYTECODE_HASH_1)).to.be.revertedWith( + "Callable only by the compressor" + ); + }); + + it("incorrectly fomatted bytecode hash failed to call", async () => { + await expect( + knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(INCORRECTLY_FORMATTED_HASH) + ).to.be.revertedWith("Incorrectly formatted bytecodeHash"); + }); + + it("invalid length bytecode hash failed to call", async () => { + await expect( + knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(INVALID_LENGTH_HASH) + ).to.be.revertedWith("Code length in words must be odd"); + }); + + it("successfuly marked", async () => { + await expect(knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(BYTECODE_HASH_1)) + .to.emit(knownCodesStorage, "MarkedAsKnown") + .withArgs(BYTECODE_HASH_1.toLowerCase(), false) + .not.emit(getMock("L1Messenger"), "Called"); + expect(await knownCodesStorage.getMarker(BYTECODE_HASH_1)).to.be.eq(1); + }); + + it("not marked second time", async () => { + await expect(knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(BYTECODE_HASH_1)).to.not.emit( + knownCodesStorage, + "MarkedAsKnown" + ); + }); + }); + + describe("markFactoryDeps", function () { + it("non-bootloader failed to call", async () => { + await expect(knownCodesStorage.markFactoryDeps(false, [BYTECODE_HASH_2, BYTECODE_HASH_3])).to.be.revertedWith( + "Callable only by the bootloader" + ); + }); + + it("incorrectly fomatted bytecode hash failed to call", async () => { + await expect( + knownCodesStorage + .connect(bootloaderAccount) + .markFactoryDeps(true, [BYTECODE_HASH_2, INCORRECTLY_FORMATTED_HASH]) + ).to.be.revertedWith("Incorrectly formatted bytecodeHash"); + }); + + it("invalid length bytecode hash failed to call", async () => { + await expect( + knownCodesStorage.connect(bootloaderAccount).markFactoryDeps(false, [INVALID_LENGTH_HASH, BYTECODE_HASH_3]) + ).to.be.revertedWith("Code length in words must be odd"); + }); + + it("successfuly marked", async () => { + await expect( + knownCodesStorage.connect(bootloaderAccount).markFactoryDeps(false, [BYTECODE_HASH_2, BYTECODE_HASH_3]) + ) + .to.emit(knownCodesStorage, "MarkedAsKnown") + .withArgs(BYTECODE_HASH_2.toLowerCase(), false) + .emit(knownCodesStorage, "MarkedAsKnown") + .withArgs(BYTECODE_HASH_3.toLowerCase(), false) + .not.emit(getMock("L1Messenger"), "Called"); + expect(await knownCodesStorage.getMarker(BYTECODE_HASH_2)).to.be.eq(1); + expect(await knownCodesStorage.getMarker(BYTECODE_HASH_3)).to.be.eq(1); + }); + + it("not marked second time", async () => { + await expect( + knownCodesStorage.connect(bootloaderAccount).markFactoryDeps(false, [BYTECODE_HASH_2, BYTECODE_HASH_3]) + ).to.not.emit(knownCodesStorage, "MarkedAsKnown"); + }); + + it("sent to l1", async () => { + await expect(knownCodesStorage.connect(bootloaderAccount).markFactoryDeps(true, [BYTECODE_HASH_4])) + .to.emit(knownCodesStorage, "MarkedAsKnown") + .withArgs(BYTECODE_HASH_4.toLowerCase(), true) + .emit(getMock("L1Messenger"), "Called") + .withArgs(0, await encodeCalldata("L1Messenger", "requestBytecodeL1Publication", [BYTECODE_HASH_4])); + expect(await knownCodesStorage.getMarker(BYTECODE_HASH_4)).to.be.eq(1); + }); + }); + + describe("getMarker", function () { + it("not known", async () => { + expect(await knownCodesStorage.getMarker(INCORRECTLY_FORMATTED_HASH)).to.be.eq(0); + }); + + it("known", async () => { + expect(await knownCodesStorage.getMarker(BYTECODE_HASH_1)).to.be.eq(1); + }); + }); +}); diff --git a/system-contracts/test/L2EthToken.spec.ts b/system-contracts/test/L2EthToken.spec.ts new file mode 100644 index 000000000..d7d8923f9 --- /dev/null +++ b/system-contracts/test/L2EthToken.spec.ts @@ -0,0 +1,237 @@ +import { expect } from "chai"; +import { ethers, network } from "hardhat"; +import type { Wallet } from "zksync-web3"; +import type { L2EthToken } from "../typechain"; +import { L2EthTokenFactory } from "../typechain"; +import { deployContractOnAddress, getWallets, loadArtifact, provider } from "./shared/utils"; +import type { BigNumber } from "ethers"; +import { TEST_BOOTLOADER_FORMAL_ADDRESS, TEST_ETH_TOKEN_SYSTEM_CONTRACT_ADDRESS } from "./shared/constants"; +import { prepareEnvironment, setResult } from "./shared/mocks"; +import { randomBytes } from "crypto"; + +describe("L2EthToken tests", () => { + const richWallet = getWallets()[0]; + let wallets: Array; + let l2EthToken: L2EthToken; + let bootloaderAccount: ethers.Signer; + let mailboxIface: ethers.utils.Interface; + + before(async () => { + await prepareEnvironment(); + await deployContractOnAddress(TEST_ETH_TOKEN_SYSTEM_CONTRACT_ADDRESS, "L2EthToken"); + l2EthToken = L2EthTokenFactory.connect(TEST_ETH_TOKEN_SYSTEM_CONTRACT_ADDRESS, richWallet); + bootloaderAccount = await ethers.getImpersonatedSigner(TEST_BOOTLOADER_FORMAL_ADDRESS); + mailboxIface = new ethers.utils.Interface((await loadArtifact("IMailbox")).abi); + }); + + beforeEach(async () => { + wallets = Array.from({ length: 2 }, () => ethers.Wallet.createRandom().connect(provider)); + }); + + after(async function () { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_BOOTLOADER_FORMAL_ADDRESS], + }); + }); + + describe("mint", () => { + it("called by bootlader", async () => { + const initialSupply: BigNumber = await l2EthToken.totalSupply(); + const initialBalanceOfWallet: BigNumber = await l2EthToken.balanceOf(wallets[0].address); + const amountToMint: BigNumber = ethers.utils.parseEther("10.0"); + + await expect(l2EthToken.connect(bootloaderAccount).mint(wallets[0].address, amountToMint)) + .to.emit(l2EthToken, "Mint") + .withArgs(wallets[0].address, amountToMint); + + const finalSupply: BigNumber = await l2EthToken.totalSupply(); + const balanceOfWallet: BigNumber = await l2EthToken.balanceOf(wallets[0].address); + expect(finalSupply).to.equal(initialSupply.add(amountToMint)); + expect(balanceOfWallet).to.equal(initialBalanceOfWallet.add(amountToMint)); + }); + + it("not called by bootloader", async () => { + const amountToMint: BigNumber = ethers.utils.parseEther("10.0"); + await expect(l2EthToken.connect(wallets[0]).mint(wallets[0].address, amountToMint)).to.be.rejectedWith( + "Callable only by the bootloader" + ); + }); + }); + + describe("transfer", () => { + it("transfer successfully", async () => { + await ( + await l2EthToken.connect(bootloaderAccount).mint(wallets[0].address, ethers.utils.parseEther("100.0")) + ).wait(); + + const senderBalanceBeforeTransfer: BigNumber = await l2EthToken.balanceOf(wallets[0].address); + const recipientBalanceBeforeTransfer: BigNumber = await l2EthToken.balanceOf(wallets[1].address); + + const amountToTransfer = ethers.utils.parseEther("10.0"); + + await expect( + l2EthToken.connect(bootloaderAccount).transferFromTo(wallets[0].address, wallets[1].address, amountToTransfer) + ) + .to.emit(l2EthToken, "Transfer") + .withArgs(wallets[0].address, wallets[1].address, amountToTransfer); + + const senderBalanceAfterTransfer: BigNumber = await l2EthToken.balanceOf(wallets[0].address); + const recipientBalanceAfterTransfer: BigNumber = await l2EthToken.balanceOf(wallets[1].address); + expect(senderBalanceAfterTransfer).to.be.eq(senderBalanceBeforeTransfer.sub(amountToTransfer)); + expect(recipientBalanceAfterTransfer).to.be.eq(recipientBalanceBeforeTransfer.add(amountToTransfer)); + }); + + it("no tranfser due to insufficient balance", async () => { + await ( + await l2EthToken.connect(bootloaderAccount).mint(wallets[0].address, ethers.utils.parseEther("5.0")) + ).wait(); + const amountToTransfer: BigNumber = ethers.utils.parseEther("6.0"); + + await expect( + l2EthToken.connect(bootloaderAccount).transferFromTo(wallets[0].address, wallets[1].address, amountToTransfer) + ).to.be.rejectedWith("Transfer amount exceeds balance"); + }); + + it("no transfer - require special access", async () => { + const maliciousWallet: Wallet = ethers.Wallet.createRandom().connect(provider); + await ( + await l2EthToken.connect(bootloaderAccount).mint(maliciousWallet.address, ethers.utils.parseEther("20.0")) + ).wait(); + + const amountToTransfer: BigNumber = ethers.utils.parseEther("20.0"); + + await expect( + l2EthToken + .connect(maliciousWallet) + .transferFromTo(maliciousWallet.address, wallets[1].address, amountToTransfer) + ).to.be.rejectedWith("Only system contracts with special access can call this method"); + }); + }); + + describe("balanceOf", () => { + it("walletFrom address", async () => { + const amountToMint: BigNumber = ethers.utils.parseEther("10.0"); + + await l2EthToken.connect(bootloaderAccount).mint(wallets[0].address, amountToMint); + const balance = await l2EthToken.balanceOf(wallets[0].address); + expect(balance).to.equal(amountToMint); + }); + + it("address larger than 20 bytes", async () => { + const amountToMint: BigNumber = ethers.utils.parseEther("123.0"); + + const res = await l2EthToken.connect(bootloaderAccount).mint(wallets[0].address, amountToMint); + await res.wait(); + const largerAddress = ethers.BigNumber.from( + "0x" + randomBytes(12).toString("hex") + wallets[0].address.slice(2) + ).toHexString(); + const balance = await l2EthToken.balanceOf(largerAddress); + + expect(balance).to.equal(amountToMint); + }); + }); + + describe("totalSupply", () => { + it("correct total supply", async () => { + const totalSupplyBefore = await l2EthToken.totalSupply(); + const amountToMint: BigNumber = ethers.utils.parseEther("10.0"); + + await l2EthToken.connect(bootloaderAccount).mint(wallets[0].address, amountToMint); + const totalSupply = await l2EthToken.totalSupply(); + + expect(totalSupply).to.equal(totalSupplyBefore.add(amountToMint)); + }); + }); + + describe("name", () => { + it("correct name", async () => { + const name = await l2EthToken.name(); + expect(name).to.equal("Ether"); + }); + }); + + describe("symbol", () => { + it("correct symbol", async () => { + const symbol = await l2EthToken.symbol(); + expect(symbol).to.equal("ETH"); + }); + }); + + describe("decimals", () => { + it("correct decimals", async () => { + const decimals = await l2EthToken.decimals(); + expect(decimals).to.equal(18); + }); + }); + + describe("withdraw", () => { + it("event, balance, totalsupply", async () => { + const amountToWithdraw: BigNumber = ethers.utils.parseEther("1.0"); + const message: string = ethers.utils.solidityPack( + ["bytes4", "address", "uint256"], + [mailboxIface.getSighash("finalizeEthWithdrawal"), wallets[1].address, amountToWithdraw] + ); + + await setResult("L1Messenger", "sendToL1", [message], { + failure: false, + returnData: ethers.utils.defaultAbiCoder.encode(["bytes32"], [ethers.utils.keccak256(message)]), + }); + + // To prevent underflow since initial values are 0's and we are substracting from them + const amountToMint: BigNumber = ethers.utils.parseEther("100.0"); + await (await l2EthToken.connect(bootloaderAccount).mint(l2EthToken.address, amountToMint)).wait(); + + const balanceBeforeWithdrawal: BigNumber = await l2EthToken.balanceOf(l2EthToken.address); + const totalSupplyBefore = await l2EthToken.totalSupply(); + + await expect(l2EthToken.connect(richWallet).withdraw(wallets[1].address, { value: amountToWithdraw })) + .to.emit(l2EthToken, "Withdrawal") + .withArgs(richWallet.address, wallets[1].address, amountToWithdraw); + + const balanceAfterWithdrawal: BigNumber = await l2EthToken.balanceOf(l2EthToken.address); + const totalSupplyAfter = await l2EthToken.totalSupply(); + + expect(balanceAfterWithdrawal).to.equal(balanceBeforeWithdrawal.sub(amountToWithdraw)); + expect(totalSupplyAfter).to.equal(totalSupplyBefore.sub(amountToWithdraw)); + }); + + it("event, balance, totalsupply, withdrawWithMessage", async () => { + const amountToWithdraw: BigNumber = ethers.utils.parseEther("1.0"); + const additionalData: string = ethers.utils.defaultAbiCoder.encode(["string"], ["additional data"]); + const message: string = ethers.utils.solidityPack( + ["bytes4", "address", "uint256", "address", "bytes"], + [ + mailboxIface.getSighash("finalizeEthWithdrawal"), + wallets[1].address, + amountToWithdraw, + richWallet.address, + additionalData, + ] + ); + + await setResult("L1Messenger", "sendToL1", [message], { + failure: false, + returnData: ethers.utils.defaultAbiCoder.encode(["bytes32"], [ethers.utils.keccak256(message)]), + }); + + // Consitency reasons - won't crash if test order reverse + const amountToMint: BigNumber = ethers.utils.parseEther("100.0"); + await (await l2EthToken.connect(bootloaderAccount).mint(l2EthToken.address, amountToMint)).wait(); + + const totalSupplyBefore = await l2EthToken.totalSupply(); + const balanceBeforeWithdrawal: BigNumber = await l2EthToken.balanceOf(l2EthToken.address); + await expect( + l2EthToken.connect(richWallet).withdrawWithMessage(wallets[1].address, additionalData, { + value: amountToWithdraw, + }) + ) + .to.emit(l2EthToken, "WithdrawalWithMessage") + .withArgs(richWallet.address, wallets[1].address, amountToWithdraw, additionalData); + const totalSupplyAfter = await l2EthToken.totalSupply(); + const balanceAfterWithdrawal: BigNumber = await l2EthToken.balanceOf(l2EthToken.address); + expect(balanceAfterWithdrawal).to.equal(balanceBeforeWithdrawal.sub(amountToWithdraw)); + expect(totalSupplyAfter).to.equal(totalSupplyBefore.sub(amountToWithdraw)); + }); + }); +}); diff --git a/system-contracts/test/precompiles/EcAdd.spec.ts b/system-contracts/test/precompiles/EcAdd.spec.ts new file mode 100644 index 000000000..499ad6843 --- /dev/null +++ b/system-contracts/test/precompiles/EcAdd.spec.ts @@ -0,0 +1,188 @@ +import { expect } from "chai"; +import type { Contract } from "zksync-web3"; +import { callFallback, deployContractYul } from "../shared/utils"; + +describe("EcAdd tests", function () { + let ecAdd: Contract; + + before(async () => { + ecAdd = await deployContractYul("EcAdd", "precompiles"); + }); + + describe("Ethereum tests", function () { + it("0 bytes: (0, 0) + (0, 0)", async () => { + const returnData = await callFallback(ecAdd, ""); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("128 bytes: (6, 9) + (19274124, 124124)", async () => { + const call = callFallback( + ecAdd, + "0x00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000126198c000000000000000000000000000000000000000000000000000000000001e4dc" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (1, 2) + (0, 0)", async () => { + const returnData = await callFallback( + ecAdd, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + }); + + it("128 bytes: (0, 0) + (0, 0)", async () => { + const returnData = await callFallback( + ecAdd, + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("128 bytes: (0, 3) + (1, 2)", async () => { + const call = callFallback( + ecAdd, + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (0, 0) + (1, 3)", async () => { + const call = callFallback( + ecAdd, + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (0, 0) + (1, 2)", async () => { + const returnData = await callFallback( + ecAdd, + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + }); + + it("64 bytes: (0, 0) + (0, 0)", async () => { + const returnData = await callFallback( + ecAdd, + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("128 bytes: (1, 2) + (1, 2)", async () => { + const returnData = await callFallback( + ecAdd, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + await expect(returnData).to.be.equal( + "0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4" + ); + }); + + it("80 bytes: (1, 3) + (0, 0)", async () => { + const call = callFallback( + ecAdd, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("192 bytes: (1, 2) + (0, 0)", async () => { + const returnData = await callFallback( + ecAdd, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + }); + + it("192 bytes: (0, 0) + (0, 0)", async () => { + const returnData = await callFallback( + ecAdd, + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("80 bytes: (0, 0) + (0, 0)", async () => { + const returnData = await callFallback( + ecAdd, + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + // (10744596414106452074759370245733544594153395043370666422502510773307029471145, 848677436511517736191562425154572367705380862894644942948681172815252343932) + // + + // (10744596414106452074759370245733544594153395043370666422502510773307029471145, 21039565435327757486054843320102702720990930294403178719740356721829973864651) + it("192 bytes: (1074..1145, 8486..3932) + (1074..1145, 2103..4651)", async () => { + const returnData = await callFallback( + ecAdd, + "0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("192 bytes: (0, 0) + (1, 2)", async () => { + const returnData = await callFallback( + ecAdd, + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + }); + + it("192 bytes: (1, 2) + (1, 2)", async () => { + const returnData = await callFallback( + ecAdd, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4" + ); + }); + + it("64 bytes: (1, 2) + (0, 0)", async () => { + const returnData = await callFallback( + ecAdd, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" + ); + }); + + // (10744596414106452074759370245733544594153395043370666422502510773307029471145, 848677436511517736191562425154572367705380862894644942948681172815252343932) + // + + // (1624070059937464756887933993293429854168590106605707304006200119738501412969, 3269329550605213075043232856820720631601935657990457502777101397807070461336) + it("128 bytes: (1074..1145, 8486..3932) + (1624..2969, 3269..1336)", async () => { + const returnData = await callFallback( + ecAdd, + "0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98" + ); + await expect(returnData).to.be.equal( + "0x15bf2bb17880144b5d1cd2b1f46eff9d617bffd1ca57c37fb5a49bd84e53cf66049c797f9ce0d17083deb32b5e36f2ea2a212ee036598dd7624c168993d1355f" + ); + }); + }); +}); diff --git a/system-contracts/test/precompiles/EcMul.spec.ts b/system-contracts/test/precompiles/EcMul.spec.ts new file mode 100644 index 000000000..bf83518ed --- /dev/null +++ b/system-contracts/test/precompiles/EcMul.spec.ts @@ -0,0 +1,399 @@ +import { expect } from "chai"; +import type { Contract } from "zksync-web3"; +import { callFallback, deployContractYul } from "../shared/utils"; + +describe("EcMul tests", function () { + let ecMul: Contract; + + before(async () => { + ecMul = await deployContractYul("EcMul", "precompiles"); + }); + + describe("Ethereum tests", function () { + it("128 bytes: (1, 3) * 0", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (1, 2) * 21888242871839275222246405745257275088548364400416034343698204186575808495616", async () => { + const returnData = await callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45" + ); + }); + + it("64 bytes: (1, 3) * 0", async () => { + const call = callFallback( + ecMul, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (1, 3) * 21888242871839275222246405745257275088548364400416034343698204186575808495616", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000330644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("96 bytes: (1, 3) * 21888242871839275222246405745257275088548364400416034343698204186575808495617", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000330644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001" + ); + await expect(call).to.be.reverted; + }); + + it("96 bytes: (1, 3) * 1", async () => { + const call = callFallback( + ecMul, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001" + ); + await expect(call).to.be.reverted; + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 21888242871839275222246405745257275088548364400416034343698204186575808495616 + it("96 bytes: (1199..7827, 1184..6598) * 2188..5616", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + ); + await expect(returnData).to.be.equal( + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451" + ); + }); + + it("128 bytes: (1, 3) * 9", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (1, 3) * 21888242871839275222246405745257275088548364400416034343698204186575808495617", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000330644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000010000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (1, 2) * 340282366920938463463374607431768211456", async () => { + const returnData = await callFallback( + ecMul, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000100000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x13b8fec4a1eb2c7e3ccc07061ad516277c3bbe57bd4a302012b58a517f6437a4224d978b5763831dff16ce9b2c42222684835fedfc70ffec005789bb0c10de36" + ); + }); + + it("96 bytes: (1, 3) * 2", async () => { + const call = callFallback( + ecMul, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002" + ); + await expect(call).to.be.reverted; + }); + + it("128 bytes: (1, 3) * 1", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("96 bytes: (1, 2) * 115792089237316195423570985008687907853269984665640564039457584007913129639935", async () => { + const returnData = await callFallback( + ecMul, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + ); + await expect(returnData).to.be.equal( + "0x2f588cffe99db877a4434b598ab28f81e0522910ea52b45f0adaa772b2d5d35212f42fa8fd34fb1b33d8c6a718b6590198389b26fc9d8808d971f8b009777a97" + ); + }); + + it("128 bytes: (1, 2) * 21888242871839275222246405745257275088548364400416034343698204186575808495617", async () => { + const returnData = await callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000010000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("128 bytes: (1, 2) * 2", async () => { + const returnData = await callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4" + ); + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 340282366920938463463374607431768211456 + it("80 bytes: (1199..7827, 1184..6598) * 340282366920938463463374607431768211456", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b" + ); + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 0 + it("96 bytes: (1199..7827, 1184..6598) * 0", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("96 bytes: (1, 3) * 9", async () => { + const call = callFallback( + ecMul, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000009" + ); + await expect(call).to.be.reverted; + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 115792089237316195423570985008687907853269984665640564039457584007913129639935 + it("96 bytes: (1, 3) * 9", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + ); + await expect(returnData).to.be.equal( + "0x2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11" + ); + }); + + it("96 bytes: (1, 3) * 115792089237316195423570985008687907853269984665640564039457584007913129639935", async () => { + const call = callFallback( + ecMul, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 0 + it("64 bytes: (1199..7827, 1184..6598) * 0", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("128 bytes: (1, 2) * 115792089237316195423570985008687907853269984665640564039457584007913129639935", async () => { + const returnData = await callFallback( + ecMul, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x2f588cffe99db877a4434b598ab28f81e0522910ea52b45f0adaa772b2d5d35212f42fa8fd34fb1b33d8c6a718b6590198389b26fc9d8808d971f8b009777a97" + ); + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 1 + it("96 bytes: (1199..7827, 1184..6598) * 1", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001" + ); + await expect(returnData).to.be.equal( + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6" + ); + }); + + it("96 bytes: (1, 2) * 9", async () => { + const returnData = await callFallback( + ecMul, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000009" + ); + await expect(returnData).to.be.equal( + "0x039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98" + ); + }); + + it("96 bytes: (1, 2) * 21888242871839275222246405745257275088548364400416034343698204186575808495617", async () => { + const returnData = await callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + it("80 bytes: (1, 3) * 340282366920938463463374607431768211456", async () => { + const call = callFallback( + ecMul, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000100000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("80 bytes: (1, 3) * 2", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("96 bytes: (1, 3) * 21888242871839275222246405745257275088548364400416034343698204186575808495616", async () => { + const call = callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000330644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + ); + await expect(call).to.be.reverted; + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 2 + it("96 bytes: (1199..7827, 1184..6598) * 2", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000002" + ); + await expect(returnData).to.be.equal( + "0x03d64e49ebb3c56c99e0769c1833879c9b86ead23945e1e7477cbd057e961c500d6840b39f8c2fefe0eced3e7d210b830f50831e756f1cc9039af65dc292e6d0" + ); + }); + + it("128 bytes: (1, 2) * 9", async () => { + const returnData = await callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98" + ); + }); + + it("96 bytes: (1, 3) * 0", async () => { + const call = callFallback( + ecMul, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 21888242871839275222246405745257275088548364400416034343698204186575808495617 + it("96 bytes: (1199..7827, 1184..6598) * 2188..5617", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 9 + it("96 bytes: (1199..7827, 1184..6598) * 9", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009" + ); + await expect(returnData).to.be.equal( + "0x1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575" + ); + }); + + it("96 bytes: (1, 2) * 21888242871839275222246405745257275088548364400416034343698204186575808495616", async () => { + const returnData = await callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" + ); + await expect(returnData).to.be.equal( + "0x000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45" + ); + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 2 + it("128 bytes: (1199..7827, 1184..6598) * 2", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x03d64e49ebb3c56c99e0769c1833879c9b86ead23945e1e7477cbd057e961c500d6840b39f8c2fefe0eced3e7d210b830f50831e756f1cc9039af65dc292e6d0" + ); + }); + + it("128 bytes: (1, 2) * 340282366920938463463374607431768211456", async () => { + const returnData = await callFallback( + ecMul, + "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x13b8fec4a1eb2c7e3ccc07061ad516277c3bbe57bd4a302012b58a517f6437a4224d978b5763831dff16ce9b2c42222684835fedfc70ffec005789bb0c10de36" + ); + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 115792089237316195423570985008687907853269984665640564039457584007913129639935 + it("128 bytes: (1199..7827, 1184..6598) * 1157..9935", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11" + ); + }); + + // (11999875504842010600789954262886096740416429265635183817701593963271973497827, 11843594000332171325303933275547366297934113019079887694534126289021216356598) + // * + // 21888242871839275222246405745257275088548364400416034343698204186575808495617 + it("128 bytes: (1199..7827, 1184..6598) * 2188..5617", async () => { + const returnData = await callFallback( + ecMul, + "0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000010000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + }); + }); +}); diff --git a/system-contracts/test/shared/constants.ts b/system-contracts/test/shared/constants.ts new file mode 100644 index 000000000..20f4586fd --- /dev/null +++ b/system-contracts/test/shared/constants.ts @@ -0,0 +1,24 @@ +import { BigNumber } from "ethers"; + +export const TEST_BOOTLOADER_FORMAL_ADDRESS = "0x0000000000000000000000000000000000009001"; +export const TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009002"; +export const TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009003"; +export const TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009004"; +export const TEST_IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009005"; +export const TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009006"; +export const TEST_FORCE_DEPLOYER_ADDRESS = "0x0000000000000000000000000000000000009007"; +export const TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009008"; +export const TEST_MSG_VALUE_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009009"; +export const TEST_ETH_TOKEN_SYSTEM_CONTRACT_ADDRESS = "0x000000000000000000000000000000000000900a"; +export const TEST_BOOTLOADER_UTILITIES_ADDRESS = "0x000000000000000000000000000000000000900c"; +export const TEST_COMPRESSOR_CONTRACT_ADDRESS = "0x000000000000000000000000000000000000900e"; +export const TEST_COMPLEX_UPGRADER_CONTRACT_ADDRESS = "0x000000000000000000000000000000000000900f"; + +// event writer should be on the original address because event logs are filtered by address +export const REAL_EVENT_WRITER_CONTRACT_ADDRESS = "0x000000000000000000000000000000000000800d"; +export const REAL_DEPLOYER_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000008006"; +export const REAL_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000008002"; + +export const EMPTY_STRING_KECCAK = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"; +export const TWO_IN_256 = BigNumber.from(2).pow(256); +export const ONE_BYTES32_HEX = "0x0000000000000000000000000000000000000000000000000000000000000001"; diff --git a/system-contracts/test/shared/extraAbiCaller.ts b/system-contracts/test/shared/extraAbiCaller.ts new file mode 100644 index 000000000..2f3c3efad --- /dev/null +++ b/system-contracts/test/shared/extraAbiCaller.ts @@ -0,0 +1,21 @@ +import type { BigNumber } from "ethers"; +import { ethers } from "hardhat"; + +// kernel space is required to set the context u128 value +export const EXTRA_ABI_CALLER_ADDRESS = "0x000000000000000000000000000000000000BEEF"; +const EXTRA_ABI_REGISTERS_NUMBER = 10; + +export function encodeExtraAbiCallerCalldata( + to: string, + value: BigNumber, + extraData: string[], + calldata: string +): string { + if (extraData.length > EXTRA_ABI_REGISTERS_NUMBER) throw "Too big extraData length"; + extraData.push(...Array(EXTRA_ABI_REGISTERS_NUMBER - extraData.length).fill(ethers.constants.HashZero)); + const encodedData = ethers.utils.defaultAbiCoder.encode( + ["address", "uint256", `uint256[${EXTRA_ABI_REGISTERS_NUMBER}]`], + [to, value, extraData] + ); + return ethers.utils.hexConcat([encodedData, calldata]); +} diff --git a/system-contracts/test/shared/mocks.ts b/system-contracts/test/shared/mocks.ts new file mode 100644 index 000000000..6fb6aea36 --- /dev/null +++ b/system-contracts/test/shared/mocks.ts @@ -0,0 +1,76 @@ +import { ethers } from "hardhat"; +import type { MockContract } from "../../typechain"; +import { MockContractFactory } from "../../typechain"; +import { + TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, + TEST_BOOTLOADER_FORMAL_ADDRESS, + TEST_ETH_TOKEN_SYSTEM_CONTRACT_ADDRESS, + TEST_IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT_ADDRESS, + TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, + TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, + TEST_MSG_VALUE_SYSTEM_CONTRACT_ADDRESS, + TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, +} from "./constants"; +import { deployContractOnAddress, getWallets, loadArtifact } from "./utils"; + +type CallResult = { + failure: boolean; + returnData: string; +}; + +// Currently listed only contracts, that actually need to be mocked in the tests. +// But other contracts can be added if needed. +const TEST_SYSTEM_CONTRACTS_MOCKS = { + NonceHolder: TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, + L1Messenger: TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, + KnownCodesStorage: TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, + AccountCodeStorage: TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, + L2EthToken: TEST_ETH_TOKEN_SYSTEM_CONTRACT_ADDRESS, + ImmutableSimulator: TEST_IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT_ADDRESS, + MsgValueSimulator: TEST_MSG_VALUE_SYSTEM_CONTRACT_ADDRESS, + Bootloader: TEST_BOOTLOADER_FORMAL_ADDRESS, +}; + +// Deploys mocks, and cleans previous call results during deployments. +// Usually should be called once per one system contract tests set. +export async function prepareEnvironment() { + for (const address of Object.values(TEST_SYSTEM_CONTRACTS_MOCKS)) { + await deployContractOnAddress(address, "MockContract"); + } +} + +// set the call result for the mocked system contract +export async function setResult( + contractName: string, + functionName: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + args: any[] | string | undefined, + result: CallResult +) { + const mock = getMock(contractName); + const calldata = encodeCalldata(contractName, functionName, args); + await mock.setResult({ input: calldata, failure: result.failure, returnData: result.returnData }); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export async function encodeCalldata(contractName: string, functionName: string, args: any[] | string | undefined) { + let calldata: string; + if (functionName === "") { + if (typeof args !== "string") { + throw "Invalid args for the fallback"; + } + calldata = args; + } else { + const iface = new ethers.utils.Interface((await loadArtifact(contractName)).abi); + calldata = iface.encodeFunctionData(functionName, args); + } + return calldata; +} + +export function getMock(contractName: string): MockContract { + const address = TEST_SYSTEM_CONTRACTS_MOCKS[contractName]; + if (address === undefined) { + throw `Test system contract ${contractName} not found`; + } + return MockContractFactory.connect(address, getWallets()[0]); +} diff --git a/system-contracts/test/shared/transactions.ts b/system-contracts/test/shared/transactions.ts new file mode 100644 index 000000000..73c4fcc21 --- /dev/null +++ b/system-contracts/test/shared/transactions.ts @@ -0,0 +1,150 @@ +import type { BigNumberish, BytesLike, Transaction } from "ethers"; +import * as zksync from "zksync-web3"; + +// Interface encoding the transaction struct used for AA protocol +export interface TransactionData { + txType: BigNumberish; + from: BigNumberish; + to: BigNumberish; + gasLimit: BigNumberish; + gasPerPubdataByteLimit: BigNumberish; + maxFeePerGas: BigNumberish; + maxPriorityFeePerGas: BigNumberish; + paymaster: BigNumberish; + nonce: BigNumberish; + value: BigNumberish; + // In the future, we might want to add some + // new fields to the struct. The `txData` struct + // is to be passed to account and any changes to its structure + // would mean a breaking change to these accounts. In order to prevent this, + // we should keep some fields as "reserved". + // It is also recommneded that their length is fixed, since + // it would allow easier proof integration (in case we will need + // some special circuit for preprocessing transactions). + reserved: [BigNumberish, BigNumberish, BigNumberish, BigNumberish]; + data: BytesLike; + signature: BytesLike; + factoryDeps: BytesLike[]; + paymasterInput: BytesLike; + // Reserved dynamic type for the future use-case. Using it should be avoided, + // But it is still here, just in case we want to enable some additional functionality. + reservedDynamic: BytesLike; +} + +export function signedTxToTransactionData(tx: Transaction) { + // Transform legacy transaction's `v` part of the signature + // to a single byte used in the packed eth signature + function unpackV(v: number) { + if (v >= 35) { + const chainId = Math.floor((v - 35) / 2); + return v - chainId * 2 - 8; + } else if (v <= 1) { + return 27 + v; + } + + throw new Error("Invalid `v`"); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function legacyTxToTransactionData(tx: any): TransactionData { + return { + txType: 0, + from: tx.from!, + to: tx.to!, + gasLimit: tx.gasLimit!, + gasPerPubdataByteLimit: zksync.utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + maxFeePerGas: tx.gasPrice!, + maxPriorityFeePerGas: tx.gasPrice!, + paymaster: 0, + nonce: tx.nonce, + value: tx.value || 0, + reserved: [tx.chainId || 0, 0, 0, 0], + data: tx.data!, + signature: ethers.utils.hexConcat([tx.r, tx.s, new Uint8Array([unpackV(tx.v)])]), + factoryDeps: [], + paymasterInput: "0x", + reservedDynamic: "0x", + }; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function eip2930TxToTransactionData(tx: any): TransactionData { + return { + txType: 1, + from: tx.from!, + to: tx.to!, + gasLimit: tx.gasLimit!, + gasPerPubdataByteLimit: zksync.utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + maxFeePerGas: tx.gasPrice!, + maxPriorityFeePerGas: tx.gasPrice!, + paymaster: 0, + nonce: tx.nonce, + value: tx.value || 0, + reserved: [0, 0, 0, 0], + data: tx.data!, + signature: ethers.utils.hexConcat([tx.r, tx.s, unpackV(tx.v)]), + factoryDeps: [], + paymasterInput: "0x", + reservedDynamic: "0x", + }; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function eip1559TxToTransactionData(tx: any): TransactionData { + return { + txType: 2, + from: tx.from!, + to: tx.to!, + gasLimit: tx.gasLimit!, + gasPerPubdataByteLimit: zksync.utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + maxFeePerGas: tx.maxFeePerGas, + maxPriorityFeePerGas: tx.maxPriorityFeePerGas, + paymaster: 0, + nonce: tx.nonce, + value: tx.value || 0, + reserved: [0, 0, 0, 0], + data: tx.data!, + signature: ethers.utils.hexConcat([tx.r, tx.s, unpackV(tx.v)]), + factoryDeps: [], + paymasterInput: "0x", + reservedDynamic: "0x", + }; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function eip712TxToTransactionData(tx: any): TransactionData { + return { + txType: 113, + from: tx.from!, + to: tx.to!, + gasLimit: tx.gasLimit!, + gasPerPubdataByteLimit: tx.customData.gasPerPubdata || zksync.utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + maxFeePerGas: tx.maxFeePerGas, + maxPriorityFeePerGas: tx.maxPriorityFeePerGas, + paymaster: tx.customData.paymasterParams?.paymaster || 0, + nonce: tx.nonce, + value: tx.value || 0, + reserved: [0, 0, 0, 0], + data: tx.data!, + signature: tx.customData.customSignature, + factoryDeps: tx.customData.factoryDeps.map(zksync.utils.hashBytecode), + paymasterInput: tx.customData.paymasterParams?.paymasterInput || "0x", + reservedDynamic: "0x", + }; + } + + const txType = tx.type ?? 0; + + switch (txType) { + case 0: + return legacyTxToTransactionData(tx); + case 1: + return eip2930TxToTransactionData(tx); + case 2: + return eip1559TxToTransactionData(tx); + case 113: + return eip712TxToTransactionData(tx); + default: + throw new Error("Unsupported tx type"); + } +} diff --git a/system-contracts/test/shared/utils.ts b/system-contracts/test/shared/utils.ts new file mode 100644 index 000000000..bde6af669 --- /dev/null +++ b/system-contracts/test/shared/utils.ts @@ -0,0 +1,169 @@ +import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; +import type { ZkSyncArtifact } from "@matterlabs/hardhat-zksync-deploy/dist/types"; +import type { BytesLike } from "ethers"; +import * as hre from "hardhat"; +import { ethers } from "hardhat"; +import type { Contract } from "zksync-web3"; +import * as zksync from "zksync-web3"; +import { Provider, utils, Wallet } from "zksync-web3"; +import { Language } from "../../scripts/constants"; +import { readYulBytecode, readZasmBytecode } from "../../scripts/utils"; +import { AccountCodeStorageFactory, ContractDeployerFactory } from "../../typechain"; +import { REAL_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, REAL_DEPLOYER_SYSTEM_CONTRACT_ADDRESS } from "./constants"; + +const RICH_WALLETS = [ + { + address: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + privateKey: "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110", + }, + { + address: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618", + privateKey: "0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3", + }, + { + address: "0x0D43eB5B8a47bA8900d84AA36656c92024e9772e", + privateKey: "0xd293c684d884d56f8d6abd64fc76757d3664904e309a0645baf8522ab6366d9e", + }, + { + address: "0xA13c10C0D5bd6f79041B9835c63f91de35A15883", + privateKey: "0x850683b40d4a740aa6e745f889a6fdc8327be76e122f5aba645a5b02d0248db8", + }, +]; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const provider = new Provider((hre.network.config as any).url); + +const wallet = new Wallet(RICH_WALLETS[0].privateKey, provider); +// TODO(EVM-392): refactor to avoid `any` here. +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const deployer = new Deployer(hre, wallet as any); + +export async function callFallback(contract: Contract, data: string) { + // `eth_Call` revert is not parsed by ethers, so we send + // transaction to catch the error and use `eth_Call` to the return data. + await contract.fallback({ data }); + return contract.provider.call({ + to: contract.address, + data, + }); +} + +export function getWallets(): Wallet[] { + const wallets = []; + for (let i = 0; i < RICH_WALLETS.length; i++) { + wallets[i] = new Wallet(RICH_WALLETS[i].privateKey, provider); + } + return wallets; +} + +export async function loadArtifact(name: string): Promise { + return await deployer.loadArtifact(name); +} + +export function loadYulBytecode(codeName: string, path: string): string { + return readYulBytecode({ + codeName, + path, + lang: Language.Yul, + address: "0x0000000000000000000000000000000000000000", + }); +} + +export function loadZasmBytecode(codeName: string, path: string): string { + return readZasmBytecode({ + codeName, + path, + lang: Language.Zasm, + address: "0x0000000000000000000000000000000000000000", + }); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export async function deployContract(name: string, constructorArguments?: any[] | undefined): Promise { + const artifact = await loadArtifact(name); + return await deployer.deploy(artifact, constructorArguments); +} + +export async function deployContractYul(codeName: string, path: string): Promise { + const bytecode = loadYulBytecode(codeName, path); + return deployBytecode(bytecode); +} + +export async function deployContractZasm(codeName: string, path: string): Promise { + const bytecode = loadZasmBytecode(codeName, path); + return deployBytecode(bytecode); +} + +async function deployBytecode(bytecode: string): Promise { + return await deployer.deploy( + { + bytecode, + factoryDeps: {}, + sourceMapping: "", + _format: "", + contractName: "", + sourceName: "", + abi: [], + deployedBytecode: bytecode, + linkReferences: {}, + deployedLinkReferences: {}, + }, + [] + ); +} + +export async function deployContractOnAddress(address: string, name: string) { + const artifact = await loadArtifact(name); + await setCode(address, artifact.bytecode, true); +} + +export async function publishBytecode(bytecode: BytesLike) { + await wallet.sendTransaction({ + type: 113, + to: ethers.constants.AddressZero, + data: "0x", + customData: { + factoryDeps: [bytecode], + gasPerPubdata: 50000, + }, + }); +} + +export async function getCode(address: string): Promise { + return await provider.getCode(address); +} + +// Force deploy bytecode on the address +export async function setCode(address: string, bytecode: BytesLike, callConstructor: boolean = false) { + // TODO: think about factoryDeps with eth_sendTransaction + try { + // publish bytecode in a separate tx + await publishBytecode(bytecode); + } catch { + // ignore error + } + + const deployerAccount = await ethers.getImpersonatedSigner(REAL_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + const deployerContract = ContractDeployerFactory.connect(REAL_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, deployerAccount); + + const deployment = { + bytecodeHash: zksync.utils.hashBytecode(bytecode), + newAddress: address, + callConstructor, + value: 0, + input: "0x", + }; + await deployerContract.forceDeployOnAddress(deployment, ethers.constants.AddressZero); +} + +export async function setConstructingCodeHash(address: string, bytecode: string) { + const deployerAccount = await ethers.getImpersonatedSigner(REAL_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + const accountCodeStorage = AccountCodeStorageFactory.connect( + REAL_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, + deployerAccount + ); + + const bytecodeHash = utils.hashBytecode(bytecode); + bytecodeHash[1] = 1; + await accountCodeStorage.storeAccountConstructingCodeHash(address, bytecodeHash); +} diff --git a/tools/README.md b/tools/README.md index 2f9db93a5..51f16b00a 100644 --- a/tools/README.md +++ b/tools/README.md @@ -5,5 +5,5 @@ To generate the verifier from the scheduler key in 'data' directory, just run: ```shell -cargo run --bin zksync_verifier_contract_generator --release -- --input_path data/scheduler_key.json --output_path ../ethereum/contracts/zksync/Verifier.sol +cargo run --bin zksync_verifier_contract_generator --release -- --input_path data/scheduler_key.json --output_path ../l1-contracts/contracts/zksync/Verifier.sol ``` diff --git a/ethereum/yarn.lock b/yarn.lock similarity index 88% rename from ethereum/yarn.lock rename to yarn.lock index cadb8a168..25c4f87da 100644 --- a/ethereum/yarn.lock +++ b/yarn.lock @@ -15,20 +15,38 @@ "@babel/highlight" "^7.22.13" chalk "^2.4.2" -"@babel/helper-validator-identifier@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz#601fa28e4cc06786c18912dca138cec73b882044" - integrity sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== "@babel/highlight@^7.22.13": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.13.tgz#9cda839e5d3be9ca9e8c26b6dd69e7548f0cbf16" - integrity sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ== + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== dependencies: - "@babel/helper-validator-identifier" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" +"@balena/dockerignore@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" + integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== + +"@blakek/curry@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@blakek/curry/-/curry-2.0.2.tgz#979e927bcf5fa0426d2af681d7131df5791d1cd4" + integrity sha512-B/KkDnZqm9Y92LwETU80BaxbQ61bYTR2GaAY41mKisaICwBoC8lcuw7lwQLl52InMhviCTJBO39GJOA8d+BrVw== + +"@blakek/deep@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@blakek/deep/-/deep-2.2.0.tgz#eb97488e4a0943df4da09ad50efba4a98789f5e5" + integrity sha512-aRq/qF1yrlhCWNk2tI4epXNpo+cA8/MrxsR5oIkpKKNYtYOQKjAxRMbgnhASPx+b328MkDN+T706yFKJg8VZkQ== + dependencies: + "@blakek/curry" "^2.0.2" + pathington "^1.1.7" + "@chainsafe/as-sha256@^0.3.1": version "0.3.1" resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" @@ -101,14 +119,14 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" - integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== -"@eslint/eslintrc@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" - integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== +"@eslint/eslintrc@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" + integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -120,10 +138,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.52.0": - version "8.52.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.52.0.tgz#78fe5f117840f69dc4a353adf9b9cd926353378c" - integrity sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA== +"@eslint/js@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" + integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== "@ethereum-waffle/chai@^3.4.4": version "3.4.4" @@ -178,6 +196,20 @@ patch-package "^6.2.2" postinstall-postinstall "^2.1.0" +"@ethereumjs/rlp@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" + integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== + +"@ethereumjs/util@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" + integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + ethereum-cryptography "^2.0.0" + micro-ftch "^0.3.1" + "@ethersproject/abi@5.0.0-beta.153": version "5.0.0-beta.153" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" @@ -193,7 +225,7 @@ "@ethersproject/properties" ">=5.0.0-beta.131" "@ethersproject/strings" ">=5.0.0-beta.130" -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.7.0": +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== @@ -535,6 +567,11 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" +"@fastify/busboy@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" + integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== + "@humanwhocodes/config-array@^0.11.13": version "0.11.13" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" @@ -555,14 +592,14 @@ integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== "@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@0.3.9": version "0.3.9" @@ -572,11 +609,104 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@ljharb/resumer@~0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@ljharb/resumer/-/resumer-0.0.1.tgz#8a940a9192dd31f6a1df17564bbd26dc6ad3e68d" + integrity sha512-skQiAOrCfO7vRTq53cxznMpks7wS1va95UCidALlOVWqvBAzwPVErwizDwoMqNVMEn1mDq0utxZd02eIrvF1lw== + dependencies: + "@ljharb/through" "^2.3.9" + +"@ljharb/through@^2.3.9", "@ljharb/through@~2.3.9": + version "2.3.11" + resolved "https://registry.yarnpkg.com/@ljharb/through/-/through-2.3.11.tgz#783600ff12c06f21a76cc26e33abd0b1595092f9" + integrity sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w== + dependencies: + call-bind "^1.0.2" + "@matterlabs/eslint-config-typescript@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@matterlabs/eslint-config-typescript/-/eslint-config-typescript-1.1.2.tgz#a9be4e56aedf298800f247c5049fc412f8b301a7" integrity sha512-AhiWJQr+MSE3RVfgp5XwGoMK7kNSKh6a18+T7hkNJtyycP0306I6IGmuFA5ZVbcakGb+K32fQWzepSkrNCTAGg== +"@matterlabs/hardhat-zksync-chai-matchers@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-chai-matchers/-/hardhat-zksync-chai-matchers-0.1.4.tgz#105cb0ec1367c8fcd3ce7e3773f747c71fff675b" + integrity sha512-eGQWiImg51fmayoQ7smIK/T6QZkSu38PK7xjp1RIrewGzw2ZgqFWGp40jb5oomkf8yOQPk52Hu4TwE3Ntp8CtA== + +"@matterlabs/hardhat-zksync-deploy@^0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-0.6.5.tgz#fe56bf30850e71c8d328ac1a06a100c1a0af6e3e" + integrity sha512-EZpvn8pDslfO3UA2obT8FOi5jsHhxYS5ndIR7tjL2zXKbvkbpoJR5rgKoGTJJm0riaCud674sQcxMOybVQ+2gg== + dependencies: + "@matterlabs/hardhat-zksync-solc" "0.4.2" + chalk "4.1.2" + ts-morph "^19.0.0" + +"@matterlabs/hardhat-zksync-node@^0.0.1-beta.7": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-node/-/hardhat-zksync-node-0.0.1.tgz#d44bda3c0069b149e2a67c9697eb81166b169ea6" + integrity sha512-rMabl+I813lzXINqTq5OvujQ30wsfO9mTLMPDXuYzEEhEzvnXlaVxuqynKBXrgXAxjmr+G79rqvcWgeKygtwBA== + dependencies: + "@matterlabs/hardhat-zksync-solc" "^1.0.5" + axios "^1.4.0" + chalk "4.1.2" + fs-extra "^11.1.1" + +"@matterlabs/hardhat-zksync-solc@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.1.tgz#e8e67d947098d7bb8925f968544d34e522af5a9c" + integrity sha512-fdlGf/2yZR5ihVNc2ubea1R/nNFXRONL29Fgz5FwB3azB13rPb76fkQgcFIg9zSufHsEy6zUUT029NkxLNA9Sw== + dependencies: + "@nomiclabs/hardhat-docker" "^2.0.0" + chalk "4.1.2" + dockerode "^3.3.4" + fs-extra "^11.1.1" + semver "^7.5.1" + +"@matterlabs/hardhat-zksync-solc@0.4.2", "@matterlabs/hardhat-zksync-solc@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.2.tgz#64121082e88c5ab22eb4e9594d120e504f6af499" + integrity sha512-6NFWPSZiOAoo7wNuhMg4ztj7mMEH+tLrx09WuCbcURrHPijj/KxYNsJD6Uw5lapKr7G8H7SQISGid1/MTXVmXQ== + dependencies: + "@nomiclabs/hardhat-docker" "^2.0.0" + chalk "4.1.2" + dockerode "^3.3.4" + fs-extra "^11.1.1" + proper-lockfile "^4.1.2" + semver "^7.5.1" + +"@matterlabs/hardhat-zksync-solc@^0.3.15": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.3.17.tgz#72f199544dc89b268d7bfc06d022a311042752fd" + integrity sha512-aZgQ0yfXW5xPkfuEH1d44ncWV4T2LzKZd0VVPo4PL5cUrYs2/II1FaEDp5zsf3FxOR1xT3mBsjuSrtJkk4AL8Q== + dependencies: + "@nomiclabs/hardhat-docker" "^2.0.0" + chalk "4.1.2" + dockerode "^3.3.4" + +"@matterlabs/hardhat-zksync-solc@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-1.0.5.tgz#9f128da0b47c147216dbd84c82bc58c190052afe" + integrity sha512-IBWvbGJSISNtWIz/4VBfV1NweVYK7xHmy787o6fDjntxP5P4XEklTJU3/pNBQdL5fZbIrQqMmXFMOwUXnuEY6Q== + dependencies: + "@nomiclabs/hardhat-docker" "^2.0.0" + chalk "4.1.2" + dockerode "^4.0.0" + fs-extra "^11.1.1" + proper-lockfile "^4.1.2" + semver "^7.5.1" + +"@matterlabs/hardhat-zksync-verify@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.2.1.tgz#f52cbe3670b7a6b01c8c4d0bbf3e6e13583e5d99" + integrity sha512-6awofVwsGHlyFMNTZcp05DPHpriSmmhBw0q+OC/Kn9xbdqT8E7fMJa6irvJH590UugxGerKrZDIY6uM6rwAjqQ== + dependencies: + "@matterlabs/hardhat-zksync-solc" "0.4.1" + "@nomicfoundation/hardhat-verify" "^1.0.2" + axios "^1.4.0" + chalk "4.1.2" + dockerode "^3.3.4" + "@matterlabs/prettier-config@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@matterlabs/prettier-config/-/prettier-config-1.0.3.tgz#3e2eb559c0112bbe9671895f935700dad2a15d38" @@ -593,20 +723,32 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" -"@noble/hashes@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" - integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== +"@noble/curves@1.1.0", "@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" -"@noble/hashes@~1.1.1": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" - integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== +"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" + integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== -"@noble/secp256k1@1.6.3", "@noble/secp256k1@~1.6.0": - version "1.6.3" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" - integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ== +"@noble/hashes@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + +"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" + integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -763,78 +905,121 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz#83a7367342bd053a76d04bbcf4f373fef07cf760" - integrity sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw== +"@nomicfoundation/hardhat-chai-matchers@^1.0.3", "@nomicfoundation/hardhat-chai-matchers@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz#72a2e312e1504ee5dd73fe302932736432ba96bc" + integrity sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@types/chai-as-promised" "^7.1.3" + chai-as-promised "^7.1.1" + deep-eql "^4.0.1" + ordinal "^1.0.3" -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz#1225f7da647ae1ad25a87125664704ecc0af6ccc" - integrity sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA== +"@nomicfoundation/hardhat-ethers@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz#0422c2123dec7c42e7fb2be8e1691f1d9708db56" + integrity sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw== + dependencies: + debug "^4.1.1" + lodash.isequal "^4.5.0" -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz#dbc052dcdfd50ae50fd5ae1788b69b4e0fa40040" - integrity sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg== +"@nomicfoundation/hardhat-verify@^1.0.2", "@nomicfoundation/hardhat-verify@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-1.1.1.tgz#6a433d777ce0172d1f0edf7f2d3e1df14b3ecfc1" + integrity sha512-9QsTYD7pcZaQFEA3tBb/D/oCStYDiEVDN7Dxeo/4SCyHRSm86APypxxdOMEPlGmXsAvd+p1j/dTODcpxb8aztA== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^8.1.0" + chalk "^2.4.2" + debug "^4.1.1" + lodash.clonedeep "^4.5.0" + semver "^6.3.0" + table "^6.8.0" + undici "^5.14.0" -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz#e6b2eea633995b557e74e881d2a43eab4760903d" - integrity sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ== +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" + integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz#af81107f5afa794f19988a368647727806e18dc4" - integrity sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w== +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" + integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz#6877e1da1a06a9f08446070ab6e0a5347109f868" - integrity sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw== +"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" + integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz#bb6cd83a0c259eccef4183796b6329a66cf7ebd9" - integrity sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg== +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" + integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz#9d4bca1cc9a1333fde985675083b0b7d165f6076" - integrity sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw== +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" + integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz#0db5bfc6aa952bea4098d8d2c8947b4e5c4337ee" - integrity sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw== +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" + integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz#2e0f39a2924dcd77db6b419828595e984fabcb33" - integrity sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA== +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" + integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== + +"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" + integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== + +"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" + integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" + integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== "@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz#e5ddc43ad5c0aab96e5054520d8e16212e125f50" - integrity sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg== + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" + integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.0" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.0" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.0" + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" + +"@nomiclabs/hardhat-docker@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-docker/-/hardhat-docker-2.0.2.tgz#ae964be17951275a55859ff7358e9e7c77448846" + integrity sha512-XgGEpRT3wlA1VslyB57zyAHV+oll8KnV1TjwnxxC1tpAL04/lbdwpdO5KxInVN8irMSepqFpsiSkqlcnvbE7Ng== + dependencies: + dockerode "^2.5.8" + fs-extra "^7.0.1" + node-fetch "^2.6.0" "@nomiclabs/hardhat-ethers@^2.0.0": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.2.tgz#812d48929c3bf8fe840ec29eab4b613693467679" - integrity sha512-NLDlDFL2us07C0jB/9wzvR0kuLivChJWCXTKcj3yqjZqMoYp7g7wwS157F70VHx/+9gHIBGzak5pKDwG8gEefA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz#b41053e360c31a32c2640c9a45ee981a7e603fe0" + integrity sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg== -"@nomiclabs/hardhat-etherscan@^3.1.0": +"@nomiclabs/hardhat-etherscan@^3.1.0", "@nomiclabs/hardhat-etherscan@^3.1.7": version "3.1.7" resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== @@ -850,7 +1035,7 @@ table "^6.8.0" undici "^5.14.0" -"@nomiclabs/hardhat-solpp@^2.0.0": +"@nomiclabs/hardhat-solpp@^2.0.0", "@nomiclabs/hardhat-solpp@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-solpp/-/hardhat-solpp-2.0.1.tgz#04039b3745b8d2b48c9b8bec6509e9785631aaba" integrity sha512-aWYvB91GPJcnye4Ph26Jd9BfBNNisI1iRNSbHB2i09OpxucSHAPMvvqTfWDN1HE5EMjqlTJ2rQLdlDcYqQxPJw== @@ -859,18 +1044,25 @@ solpp "^0.11.5" "@nomiclabs/hardhat-waffle@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz#9c538a09c5ed89f68f5fd2dc3f78f16ed1d6e0b1" - integrity sha512-049PHSnI1CZq6+XTbrMbMv5NaL7cednTfPenx02k3cEh8wBMLa6ys++dBETJa6JjfwgA9nBhhHQ173LJv6k2Pg== - dependencies: - "@types/sinon-chai" "^3.2.3" - "@types/web3" "1.0.19" + version "2.0.6" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz#d11cb063a5f61a77806053e54009c40ddee49a54" + integrity sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg== + +"@openzeppelin/contracts-upgradeable@4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.6.0.tgz#1bf55f230f008554d4c6fe25eb165b85112108b0" + integrity sha512-5OnVuO4HlkjSCJO165a4i2Pu1zQGzMs//o54LPrwUgxvEO2P3ax1QuaSI0cEHHTveA77guS0PnNugpR2JMsPfA== "@openzeppelin/contracts-upgradeable@4.8.0": version "4.8.0" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz#26688982f46969018e3ed3199e72a07c8d114275" integrity sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w== +"@openzeppelin/contracts@4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.6.0.tgz#c91cf64bc27f573836dba4122758b4743418c1b3" + integrity sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg== + "@openzeppelin/contracts@4.8.0": version "4.8.0" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.0.tgz#6854c37df205dd2c056bdfa1b853f5d732109109" @@ -926,25 +1118,42 @@ url "^0.11.0" "@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" + integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== -"@scure/bip32@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.0.tgz#dea45875e7fbc720c2b4560325f1cf5d2246d95b" - integrity sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q== +"@scure/bip32@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" + integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== dependencies: - "@noble/hashes" "~1.1.1" - "@noble/secp256k1" "~1.6.0" + "@noble/hashes" "~1.2.0" + "@noble/secp256k1" "~1.7.0" "@scure/base" "~1.1.0" -"@scure/bip39@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" - integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== dependencies: - "@noble/hashes" "~1.1.1" + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" + integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== + dependencies: + "@noble/hashes" "~1.2.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" "@scure/base" "~1.1.0" "@sentry/core@5.30.0": @@ -1032,10 +1241,10 @@ dependencies: antlr4ts "^0.5.0-alpha.4" -"@solidity-parser/parser@^0.16.0": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" - integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== +"@solidity-parser/parser@^0.16.0", "@solidity-parser/parser@^0.16.2": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.2.tgz#42cb1e3d88b3e8029b0c9befff00b634cd92d2fa" + integrity sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg== dependencies: antlr4ts "^0.5.0-alpha.4" @@ -1053,6 +1262,16 @@ dependencies: defer-to-connect "^2.0.0" +"@ts-morph/common@~0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.20.0.tgz#3f161996b085ba4519731e4d24c35f6cba5b80af" + integrity sha512-7uKjByfbPpwuzkstL3L5MQyuXPSKdoNG93Fmi2JoDcTf3pEP731JdRFAduRVkOs8oqxPsXKA+ScrWkdQ8t/I+Q== + dependencies: + fast-glob "^3.2.12" + minimatch "^7.4.3" + mkdirp "^2.1.6" + path-browserify "^1.0.1" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -1069,9 +1288,9 @@ integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@typechain/ethers-v5@^2.0.0": version "2.0.0" @@ -1085,13 +1304,6 @@ resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== -"@types/bn.js@*", "@types/bn.js@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" @@ -1099,6 +1311,13 @@ dependencies: "@types/node" "*" +"@types/bn.js@^5.1.0": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" + integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== + dependencies: + "@types/node" "*" + "@types/cacheable-request@^6.0.1": version "6.0.3" resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" @@ -1109,17 +1328,17 @@ "@types/node" "*" "@types/responselike" "^1.0.0" -"@types/chai-as-promised@^7.1.4": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" - integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== +"@types/chai-as-promised@^7.1.3", "@types/chai-as-promised@^7.1.4": + version "7.1.8" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" + integrity sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw== dependencies: "@types/chai" "*" "@types/chai@*", "@types/chai@^4.2.21": - version "4.3.4" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" - integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== + version "4.3.10" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.10.tgz#2ad2959d1767edee5b0e4efb1a0cd2b500747317" + integrity sha512-of+ICnbqjmFCiixUnqRulbylyXQrPqIGf/B3Jax1wIF3DvSheysQxAWvqHhZiW3IQrycvokcLcFQlveGp+vyNg== "@types/concat-stream@^1.6.0": version "1.6.1" @@ -1144,14 +1363,14 @@ "@types/node" "*" "@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" - integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== "@types/json-schema@^7.0.12": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" @@ -1165,6 +1384,11 @@ dependencies: "@types/node" "*" +"@types/lodash@^4.14.199": + version "4.14.201" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.201.tgz#76f47cb63124e806824b6c18463daf3e1d480239" + integrity sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ== + "@types/lru-cache@^5.1.0": version "5.1.1" resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" @@ -1188,17 +1412,19 @@ integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== "@types/node-fetch@^2.5.5": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" - integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== + version "2.6.9" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.9.tgz#15f529d247f1ede1824f7e7acdaa192d5f28071e" + integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA== dependencies: "@types/node" "*" - form-data "^3.0.0" + form-data "^4.0.0" "@types/node@*": - version "18.11.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" - integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== + version "20.9.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.1.tgz#9d578c610ce1e984adda087f685ace940954fe19" + integrity sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA== + dependencies: + undici-types "~5.26.4" "@types/node@^10.0.3": version "10.17.60" @@ -1210,27 +1436,32 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== +"@types/node@^17.0.34": + version "17.0.45" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" + integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== + "@types/node@^8.0.0": version "8.10.66" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== "@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.2.tgz#2dc43808e9985a2c69ff02e2d2027bd4fe33e8dc" + integrity sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew== dependencies: "@types/node" "*" "@types/prettier@^2.1.1": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" - integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/qs@^6.2.31": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + version "6.9.10" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== "@types/readable-stream@^2.3.13": version "2.3.15" @@ -1248,67 +1479,34 @@ "@types/node" "*" "@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" + integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== dependencies: "@types/node" "*" "@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.6.tgz#d60ba2349a51c2cbc5e816dcd831a42029d376bf" + integrity sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ== dependencies: "@types/node" "*" "@types/semver@^7.5.0": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" - integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== - -"@types/sinon-chai@^3.2.3": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.9.tgz#71feb938574bbadcb176c68e5ff1a6014c5e69d4" - integrity sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "10.0.13" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.13.tgz#60a7a87a70d9372d0b7b38cc03e825f46981fb83" - integrity sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ== - dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinonjs__fake-timers@*": - version "8.1.2" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz#bf2e02a3dbd4aecaf95942ecd99b7402e03fad5e" - integrity sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA== - -"@types/underscore@*": - version "1.11.4" - resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.11.4.tgz#62e393f8bc4bd8a06154d110c7d042a93751def3" - integrity sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg== - -"@types/web3@1.0.19": - version "1.0.19" - resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.0.19.tgz#46b85d91d398ded9ab7c85a5dd57cb33ac558924" - integrity sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A== - dependencies: - "@types/bn.js" "*" - "@types/underscore" "*" + version "7.5.5" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.5.tgz#deed5ab7019756c9c90ea86139106b0346223f35" + integrity sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg== "@typescript-eslint/eslint-plugin@^6.7.4": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz#06abe4265e7c82f20ade2dcc0e3403c32d4f148b" - integrity sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw== + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.11.0.tgz#52aae65174ff526576351f9ccd41cea01001463f" + integrity sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.8.0" - "@typescript-eslint/type-utils" "6.8.0" - "@typescript-eslint/utils" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" + "@typescript-eslint/scope-manager" "6.11.0" + "@typescript-eslint/type-utils" "6.11.0" + "@typescript-eslint/utils" "6.11.0" + "@typescript-eslint/visitor-keys" "6.11.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -1317,71 +1515,71 @@ ts-api-utils "^1.0.1" "@typescript-eslint/parser@^6.7.4": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.8.0.tgz#bb2a969d583db242f1ee64467542f8b05c2e28cb" - integrity sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg== - dependencies: - "@typescript-eslint/scope-manager" "6.8.0" - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/typescript-estree" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.11.0.tgz#9640d9595d905f3be4f278bf515130e6129b202e" + integrity sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ== + dependencies: + "@typescript-eslint/scope-manager" "6.11.0" + "@typescript-eslint/types" "6.11.0" + "@typescript-eslint/typescript-estree" "6.11.0" + "@typescript-eslint/visitor-keys" "6.11.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz#5cac7977385cde068ab30686889dd59879811efd" - integrity sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g== +"@typescript-eslint/scope-manager@6.11.0": + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz#621f603537c89f4d105733d949aa4d55eee5cea8" + integrity sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A== dependencies: - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" + "@typescript-eslint/types" "6.11.0" + "@typescript-eslint/visitor-keys" "6.11.0" -"@typescript-eslint/type-utils@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz#50365e44918ca0fd159844b5d6ea96789731e11f" - integrity sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g== +"@typescript-eslint/type-utils@6.11.0": + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz#d0b8b1ab6c26b974dbf91de1ebc5b11fea24e0d1" + integrity sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA== dependencies: - "@typescript-eslint/typescript-estree" "6.8.0" - "@typescript-eslint/utils" "6.8.0" + "@typescript-eslint/typescript-estree" "6.11.0" + "@typescript-eslint/utils" "6.11.0" debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.8.0.tgz#1ab5d4fe1d613e3f65f6684026ade6b94f7e3ded" - integrity sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ== +"@typescript-eslint/types@6.11.0": + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.11.0.tgz#8ad3aa000cbf4bdc4dcceed96e9b577f15e0bf53" + integrity sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA== -"@typescript-eslint/typescript-estree@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz#9565f15e0cd12f55cf5aa0dfb130a6cb0d436ba1" - integrity sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg== +"@typescript-eslint/typescript-estree@6.11.0": + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz#7b52c12a623bf7f8ec7f8a79901b9f98eb5c7990" + integrity sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ== dependencies: - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" + "@typescript-eslint/types" "6.11.0" + "@typescript-eslint/visitor-keys" "6.11.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.8.0.tgz#d42939c2074c6b59844d0982ce26a51d136c4029" - integrity sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q== +"@typescript-eslint/utils@6.11.0": + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.11.0.tgz#11374f59ef4cea50857b1303477c08aafa2ca604" + integrity sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.8.0" - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/typescript-estree" "6.8.0" + "@typescript-eslint/scope-manager" "6.11.0" + "@typescript-eslint/types" "6.11.0" + "@typescript-eslint/typescript-estree" "6.11.0" semver "^7.5.4" -"@typescript-eslint/visitor-keys@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz#cffebed56ae99c45eba901c378a6447b06be58b8" - integrity sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg== +"@typescript-eslint/visitor-keys@6.11.0": + version "6.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz#d991538788923f92ec40d44389e7075b359f3458" + integrity sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ== dependencies: - "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/types" "6.11.0" eslint-visitor-keys "^3.4.1" "@ungap/promise-all-settled@1.1.2": @@ -1399,6 +1597,14 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== +JSONStream@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" + integrity sha512-mn0KSip7N4e0UDPZHnqDsHECo5uGQrixQKnAskOM1BIB8hd7QKbd6il8IPRPudPHOeHiECoCFqhyMaRO9+nWyA== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -1464,19 +1670,14 @@ acorn-jsx@^5.3.2: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.4.1: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + version "8.3.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" + integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== -acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== +acorn@^8.4.1, acorn@^8.9.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== address@^1.0.1: version "1.2.2" @@ -1538,11 +1739,6 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== -ansi-colors@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" - integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== - ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -1570,11 +1766,6 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== -ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -1585,7 +1776,7 @@ ansi-styles@^2.2.1: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1619,7 +1810,7 @@ any-promise@^1.0.0: resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== -anymatch@~3.1.1, anymatch@~3.1.2: +anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -1743,14 +1934,14 @@ array.prototype.flatmap@^1.3.2: es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.reduce@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" - integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== +array.prototype.reduce@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz#63149931808c5fc1e1354814923d92d45f7d96d5" + integrity sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" @@ -1782,7 +1973,7 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@~0.2.3: +asn1@^0.2.6, asn1@~0.2.3: version "0.2.6" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== @@ -1882,6 +2073,15 @@ axios@^0.21.1: dependencies: follow-redirects "^1.14.0" +axios@^1.4.0, axios@^1.5.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -2438,7 +2638,7 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -bcrypt-pbkdf@^1.0.0: +bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== @@ -2456,21 +2656,14 @@ big-integer@^1.6.44: integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== bigint-crypto-utils@^3.0.23: - version "3.1.8" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d" - integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw== - dependencies: - bigint-mod-arith "^3.1.0" - -bigint-mod-arith@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz#658e416bc593a463d97b59766226d0a3021a76b1" - integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ== + version "3.3.0" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" + integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== bignumber.js@^9.0.0, bignumber.js@^9.0.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" - integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== binary-extensions@^2.0.0: version "2.2.0" @@ -2488,6 +2681,23 @@ bip39@2.5.0: safe-buffer "^5.0.1" unorm "^1.3.3" +bl@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + blakejs@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" @@ -2516,12 +2726,12 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: +bn.js@^5.0.0, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.1, body-parser@^1.16.0: +body-parser@1.20.1: version "1.20.1" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== @@ -2539,6 +2749,24 @@ body-parser@1.20.1, body-parser@^1.16.0: type-is "~1.6.18" unpipe "1.0.0" +body-parser@^1.16.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + bplist-parser@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" @@ -2635,7 +2863,7 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== @@ -2644,19 +2872,19 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" - integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e" + integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg== dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" + bn.js "^5.2.1" + browserify-rsa "^4.1.0" create-hash "^1.2.0" create-hmac "^1.1.7" - elliptic "^6.5.3" + elliptic "^6.5.4" inherits "^2.0.4" - parse-asn1 "^5.1.5" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" + parse-asn1 "^5.1.6" + readable-stream "^3.6.2" + safe-buffer "^5.2.1" browserslist@^3.2.6: version "3.2.8" @@ -2682,11 +2910,29 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -2731,12 +2977,17 @@ buffer@^6.0.3: ieee754 "^1.2.1" bufferutil@^4.0.1: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + version "4.0.8" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea" + integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw== dependencies: node-gyp-build "^4.3.0" +buildcheck@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238" + integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A== + bundle-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" @@ -2744,13 +2995,6 @@ bundle-name@^3.0.0: dependencies: run-applescript "^5.0.0" -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -2805,9 +3049,9 @@ cacheable-request@^6.0.0: responselike "^1.0.2" cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== dependencies: clone-response "^1.0.2" get-stream "^5.1.0" @@ -2825,15 +3069,7 @@ cachedown@1.0.0: abstract-leveldown "^2.4.1" lru-cache "^3.2.0" -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-bind@^1.0.4, call-bind@^1.0.5: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5, call-bind@~1.0.2: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== @@ -2852,20 +3088,15 @@ camelcase@^3.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - camelcase@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30000844: - version "1.0.30001443" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001443.tgz#8fc85f912d5471c9821acacf9e715c421ca0dd1f" - integrity sha512-jUo8svymO8+Mkj3qbUbVjR8zv8LUGpGkUM/jKvc9SO2BvjCI980dp9fQbf/dyLs6RascPzgR4nhAKFA4OHeSaA== + version "1.0.30001563" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz#aa68a64188903e98f36eb9c56e48fba0c1fe2a32" + integrity sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw== case@^1.6.3: version "1.6.3" @@ -2897,17 +3128,25 @@ chai-as-promised@^7.1.1: check-error "^1.0.2" chai@^4.3.4: - version "4.3.7" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" - integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== + version "4.3.10" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" + integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== dependencies: assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^4.1.2" - get-func-name "^2.0.0" - loupe "^2.3.1" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" pathval "^1.1.1" - type-detect "^4.0.5" + type-detect "^4.0.8" + +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" chalk@^1.1.3: version "1.1.3" @@ -2929,23 +3168,17 @@ chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - "charenc@>= 0.0.1": version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== +check-error@^1.0.2, check-error@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== + dependencies: + get-func-name "^2.0.2" checkpoint-store@^1.1.0: version "1.1.0" @@ -2954,21 +3187,6 @@ checkpoint-store@^1.1.0: dependencies: functional-red-black-tree "^1.0.1" -chokidar@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" - integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.2.0" - optionalDependencies: - fsevents "~2.1.1" - chokidar@3.5.3, chokidar@^3.4.0: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -2984,7 +3202,7 @@ chokidar@3.5.3, chokidar@^3.4.0: optionalDependencies: fsevents "~2.3.2" -chownr@^1.1.4: +chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -3029,14 +3247,14 @@ class-utils@^0.3.5: static-extend "^0.1.1" classic-level@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" - integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" + integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== dependencies: abstract-level "^1.0.2" catering "^2.1.0" module-error "^1.0.1" - napi-macros "~2.0.0" + napi-macros "^2.2.2" node-gyp-build "^4.3.0" clean-stack@^2.0.0: @@ -3072,15 +3290,6 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -3102,6 +3311,11 @@ clone@2.1.2, clone@^2.0.0: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== +code-block-writer@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770" + integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w== + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -3187,27 +3401,37 @@ commander@^2.19.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + commander@^8.1.0, commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@^9.4.1: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + commander@~9.4.1: version "9.4.1" resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + version "1.3.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2: +concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2, concat-stream@~1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -3233,10 +3457,10 @@ content-hash@^2.5.2: multicodec "^0.5.5" multihashes "^0.4.15" -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== convert-source-map@^1.5.1: version "1.9.0" @@ -3259,9 +3483,9 @@ cookie@^0.4.1: integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== cookiejar@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.3.tgz#fc7a6216e408e74414b90230050842dacda75acc" - integrity sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ== + version "2.1.4" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== copy-descriptor@^0.1.0: version "0.1.1" @@ -3269,9 +3493,9 @@ copy-descriptor@^0.1.0: integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== core-js-pure@^3.0.1: - version "3.27.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.27.1.tgz#ede4a6b8440585c7190062757069c01d37a19dca" - integrity sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw== + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.2.tgz#644830db2507ef84d068a70980ccd99c275f5fa6" + integrity sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q== core-js@^2.4.0, core-js@^2.5.0: version "2.6.12" @@ -3306,6 +3530,14 @@ cosmiconfig@^8.0.0: parse-json "^5.2.0" path-type "^4.0.0" +cpu-features@~0.0.8: + version "0.0.9" + resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.9.tgz#5226b92f0f1c63122b0a3eb84cb8335a4de499fc" + integrity sha512-AKjgn2rP2yJyfbepsmLfiYcmtNn/2eUvocUyM/09yB0YDiz39HteK/5/T4Onf0pmdYDMgkBoGvRLvEguzyL7wQ== + dependencies: + buildcheck "~0.0.6" + nan "^2.17.0" + crc-32@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" @@ -3450,14 +3682,14 @@ debug@4.3.3: dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.2.7: +debug@^3.1.0, debug@^3.2.6, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -decamelize@^1.1.1, decamelize@^1.2.0: +decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== @@ -3491,7 +3723,7 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" -deep-eql@^4.1.2: +deep-eql@^4.0.1, deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== @@ -3499,16 +3731,16 @@ deep-eql@^4.1.2: type-detect "^4.0.0" deep-equal@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + version "1.1.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761" + integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg== dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" + is-arguments "^1.1.1" + is-date-object "^1.0.5" + is-regex "^1.1.4" + object-is "^1.1.5" object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" + regexp.prototype.flags "^1.5.1" deep-extend@^0.6.0: version "0.6.0" @@ -3577,19 +3809,12 @@ define-lazy-prop@^3.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== -define-properties@^1.1.2, define-properties@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== dependencies: + define-data-property "^1.0.1" has-property-descriptors "^1.0.0" object-keys "^1.1.1" @@ -3615,7 +3840,7 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -defined@~1.0.0: +defined@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== @@ -3631,9 +3856,9 @@ depd@2.0.0: integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -3658,11 +3883,6 @@ detect-port@^1.3.0: address "^1.0.1" debug "4" -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -3696,6 +3916,63 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +docker-modem@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-1.0.9.tgz#a1f13e50e6afb6cf3431b2d5e7aac589db6aaba8" + integrity sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw== + dependencies: + JSONStream "1.3.2" + debug "^3.2.6" + readable-stream "~1.0.26-4" + split-ca "^1.0.0" + +docker-modem@^3.0.0: + version "3.0.8" + resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-3.0.8.tgz#ef62c8bdff6e8a7d12f0160988c295ea8705e77a" + integrity sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ== + dependencies: + debug "^4.1.1" + readable-stream "^3.5.0" + split-ca "^1.0.1" + ssh2 "^1.11.0" + +docker-modem@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-5.0.1.tgz#106bab0886d4df4ed1ea9053f1863ade4adbe846" + integrity sha512-vqrE/nrweCyzmCpVpdFRC41qS+tfTF+IoUKlTZr52O82urbUqdfyJBGWMvT01pYUprWepLr8IkyVTEWJKRTQSg== + dependencies: + debug "^4.1.1" + readable-stream "^3.5.0" + split-ca "^1.0.1" + ssh2 "^1.11.0" + +dockerode@^2.5.8: + version "2.5.8" + resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-2.5.8.tgz#1b661e36e1e4f860e25f56e0deabe9f87f1d0acc" + integrity sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw== + dependencies: + concat-stream "~1.6.2" + docker-modem "^1.0.8" + tar-fs "~1.16.3" + +dockerode@^3.3.4: + version "3.3.5" + resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-3.3.5.tgz#7ae3f40f2bec53ae5e9a741ce655fff459745629" + integrity sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA== + dependencies: + "@balena/dockerignore" "^1.0.2" + docker-modem "^3.0.0" + tar-fs "~2.0.1" + +dockerode@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-4.0.0.tgz#9c9c66926da77f6f894ad54057737a0bc7d34712" + integrity sha512-3LF7/3MPz5+9RsUo91rD0MCcx0yxjC9bnbtgtVjOLKyKxlZSJ7/Kk3OPAgARlwlWHqXwAGYhmkAHYx7IwD0tJQ== + dependencies: + "@balena/dockerignore" "^1.0.2" + docker-modem "^5.0.0" + tar-fs "~2.0.1" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -3716,9 +3993,9 @@ dom-walk@^0.1.0: integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== dotenv@^16.0.3: - version "16.0.3" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== dotignore@~0.1.2: version "0.1.2" @@ -3753,9 +4030,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.3.47: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + version "1.4.587" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.587.tgz#d8b864f21338b60798d447a3d83b90753f701d07" + integrity sha512-RyJX0q/zOkAoefZhB9XHghGeATVP0Q3mwA253XD/zj2OeXc+JZB9pCaEv6R578JUYaWM9PRhye0kXvd/V1cQ3Q== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -3770,11 +4047,6 @@ elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5 minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -3803,7 +4075,7 @@ encoding@^0.1.11: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -3819,115 +4091,37 @@ enhanced-resolve@^5.12.0: tapable "^2.2.0" enquirer@^2.3.0: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== dependencies: ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + +entities@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +errno@~0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" -entities@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" - integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -errno@~0.1.1: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6" - integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.4" - is-array-buffer "^3.0.1" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.10" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" - -es-abstract@^1.21.2: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== - dependencies: - array-buffer-byte-length "^1.0.0" - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.10" - is-weakref "^1.0.2" - object-inspect "^1.12.3" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.7" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" - es-abstract@^1.22.1: version "1.22.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" @@ -3979,13 +4173,13 @@ es-array-method-boxes-properly@^1.0.0: integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" + get-intrinsic "^1.2.2" has-tostringtag "^1.0.0" + hasown "^2.0.0" es-shim-unscopables@^1.0.0: version "1.0.2" @@ -4039,16 +4233,16 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" @@ -4135,14 +4329,14 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.51.0: - version "8.52.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.52.0.tgz#d0cd4a1fac06427a61ef9242b9353f36ea7062fc" - integrity sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg== + version "8.53.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" + integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.52.0" + "@eslint/eslintrc" "^2.1.3" + "@eslint/js" "8.53.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -4253,23 +4447,21 @@ eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: js-sha3 "^0.5.7" eth-gas-reporter@^0.2.25: - version "0.2.25" - resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566" - integrity sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ== + version "0.2.27" + resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz#928de8548a674ed64c7ba0bf5795e63079150d4e" + integrity sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw== dependencies: - "@ethersproject/abi" "^5.0.0-beta.146" "@solidity-parser/parser" "^0.14.0" + axios "^1.5.1" cli-table3 "^0.5.0" colors "1.4.0" ethereum-cryptography "^1.0.3" - ethers "^4.0.40" + ethers "^5.7.2" fs-readdir-recursive "^1.1.0" lodash "^4.17.14" markdown-table "^1.1.3" - mocha "^7.1.1" + mocha "^10.2.0" req-cwd "^2.0.0" - request "^2.88.0" - request-promise-native "^1.0.5" sha1 "^1.1.1" sync-request "^6.0.0" @@ -4416,14 +4608,24 @@ ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: setimmediate "^1.0.5" ethereum-cryptography@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz#74f2ac0f0f5fe79f012c889b3b8446a9a6264e6d" - integrity sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ== + version "1.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" + integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== + dependencies: + "@noble/hashes" "1.2.0" + "@noble/secp256k1" "1.7.1" + "@scure/bip32" "1.1.5" + "@scure/bip39" "1.1.1" + +ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" + integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== dependencies: - "@noble/hashes" "1.1.2" - "@noble/secp256k1" "1.6.3" - "@scure/bip32" "1.1.0" - "@scure/bip39" "1.1.0" + "@noble/curves" "1.1.0" + "@noble/hashes" "1.3.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" ethereum-waffle@^3.0.0: version "3.4.4" @@ -4578,7 +4780,7 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum rlp "^2.0.0" safe-buffer "^5.1.1" -ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0: +ethereumjs-util@^7.0.2: version "7.1.5" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== @@ -4642,22 +4844,7 @@ ethereumjs-wallet@0.6.5: utf8 "^3.0.0" uuid "^3.3.2" -ethers@^4.0.40: - version "4.0.49" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" - integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== - dependencies: - aes-js "3.0.0" - bn.js "^4.11.9" - elliptic "6.5.4" - hash.js "1.1.3" - js-sha3 "0.5.7" - scrypt-js "2.0.4" - setimmediate "1.0.4" - uuid "2.0.1" - xmlhttprequest "1.8.0" - -ethers@^5.0.1, ethers@^5.0.2, ethers@^5.5.2, ethers@^5.7.0, ethers@^5.7.1: +ethers@^5.0.1, ethers@^5.0.2, ethers@^5.5.2, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2, ethers@~5.7.0: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -4974,21 +5161,10 @@ fast-diff@^1.1.2, fast-diff@^1.2.0: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.0.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" - integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== +fast-glob@^3.0.3, fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1, fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -5065,13 +5241,6 @@ find-replace@^1.0.3: array-back "^1.0.4" test-value "^2.1.0" -find-up@3.0.0, find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -5111,21 +5280,14 @@ find-yarn-workspace-root@^2.0.0: micromatch "^4.0.2" flat-cache@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" - integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" keyv "^4.5.3" rimraf "^3.0.2" -flat@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" - integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== - dependencies: - is-buffer "~2.0.3" - flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" @@ -5141,10 +5303,10 @@ flow-stoplight@^1.0.0: resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" integrity sha512-rDjbZUKpN8OYhB0IE/vY/I8UWO/602IIJEU/76Tv4LvYnwHCk0BCsvz4eRr9n+FQcri7L5cyaXOo0+/Kh4HisA== -follow-redirects@^1.12.1, follow-redirects@^1.14.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.15.0: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== for-each@^0.3.3, for-each@~0.3.3: version "0.3.3" @@ -5172,10 +5334,10 @@ form-data@^2.2.0: combined-stream "^1.0.6" mime-types "^2.1.12" -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" @@ -5217,6 +5379,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -5228,6 +5395,15 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" +fs-extra@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^4.0.2, fs-extra@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" @@ -5287,36 +5463,16 @@ fs@^0.0.1-security: resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w== -fsevents@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - function.prototype.name@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" @@ -5332,7 +5488,7 @@ functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== -functions-have-names@^1.2.2, functions-have-names@^1.2.3: +functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -5379,36 +5535,17 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.1, get-caller-file@^2.0.5: +get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-intrinsic@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" +get-func-name@^2.0.1, get-func-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== @@ -5482,7 +5619,7 @@ ghost-testrpc@^0.0.2: chalk "^2.4.2" node-emoji "^1.10.0" -glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -5496,18 +5633,6 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - 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.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" @@ -5531,7 +5656,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@~7.2.3: +glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6, glob@~7.2.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -5675,12 +5800,7 @@ got@^11.8.5: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graceful-fs@^4.2.4: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -5696,12 +5816,12 @@ growl@1.10.5: integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== handlebars@^4.0.1, handlebars@^4.7.6: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: @@ -5721,12 +5841,13 @@ har-validator@~5.1.3: har-schema "^2.0.0" hardhat-contract-sizer@^2.0.2: - version "2.6.1" - resolved "https://registry.yarnpkg.com/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz#2b0046a55fa1ec96f19fdab7fde372377401c874" - integrity sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA== + version "2.10.0" + resolved "https://registry.yarnpkg.com/hardhat-contract-sizer/-/hardhat-contract-sizer-2.10.0.tgz#72646f43bfe50e9a5702c9720c9bc3e77d93a2c9" + integrity sha512-QiinUgBD5MqJZJh1hl1jc9dNnpJg7eE/w4/4GEnrcmZJJTDbVFNe3+/3Ep24XqISSkYxRz36czcPHKHd/a0dwA== dependencies: chalk "^4.0.0" cli-table3 "^0.6.0" + strip-ansi "^6.0.0" hardhat-gas-reporter@^1.0.9: version "1.0.9" @@ -5743,9 +5864,9 @@ hardhat-typechain@^0.3.3: integrity sha512-w9lm8sxqTJACY+V7vijiH+NkPExnmtiQEjsV9JKD1KgMdVk2q8y+RhvU/c4B7+7b1+HylRUCxpOIvFuB3rE4+w== hardhat@^2.18.3: - version "2.18.3" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.18.3.tgz#8fd01348795c77086fff417a4d13c521dce28fcf" - integrity sha512-JuYaTG+4ZHVjEHCW5Hn6jCHH3LpO75dtgznZpM/dLv12RcSlw/xHbeQh3FAsGahQr1epKryZcZEMHvztVZHe0g== + version "2.19.1" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.1.tgz#5e09e8070ecfc6109ba9d3a4a117ec2b0643032a" + integrity sha512-bsWa63g1GB78ZyMN08WLhFElLPA+J+pShuKD1BFO2+88g3l+BL3R07vj9deIi9dMbssxgE714Gof1dBEDGqnCw== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" @@ -5824,18 +5945,18 @@ has-flag@^4.0.0: integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - get-intrinsic "^1.1.1" + get-intrinsic "^1.2.2" has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== -has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== @@ -5878,12 +5999,10 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3, has@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" +has@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" + integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== hash-base@^3.0.0: version "3.1.0" @@ -5894,14 +6013,6 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -5965,9 +6076,9 @@ http-basic@^8.1.1: parse-cache-control "^1.0.1" http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== http-errors@2.0.0: version "2.0.0" @@ -6053,7 +6164,12 @@ ieee754@^1.1.13, ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4, ignore@~5.2.4: +ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + +ignore@~5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -6069,9 +6185,9 @@ immediate@~3.2.3: integrity sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg== immutable@^4.0.0-rc.12: - version "4.2.2" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.2.tgz#2da9ff4384a4330c36d4d1bc88e90f9e0b0ccd16" - integrity sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og== + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" @@ -6119,22 +6235,13 @@ ini@~3.0.0: resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.1.tgz#c76ec81007875bc44d544ff7a11a55d12294102d" integrity sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ== -internal-slot@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3" - integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - side-channel "^1.0.4" - internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" + get-intrinsic "^1.2.2" + hasown "^2.0.0" side-channel "^1.0.4" interpret@^1.0.0: @@ -6166,21 +6273,14 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - 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.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== +is-accessor-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz#3223b10628354644b86260db29b3e693f5ceedd4" + integrity sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA== dependencies: - kind-of "^6.0.0" + hasown "^2.0.0" -is-arguments@^1.0.4: +is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -6188,16 +6288,7 @@ is-arguments@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-array-buffer@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a" - integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-typed-array "^1.1.10" - -is-array-buffer@^3.0.2: +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== @@ -6238,7 +6329,7 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.5, is-buffer@~2.0.3: +is-buffer@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== @@ -6255,42 +6346,21 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.11.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" - integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== - dependencies: - has "^1.0.3" - -is-core-module@^2.13.0, is-core-module@^2.13.1: +is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: hasown "^2.0.0" -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== +is-data-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz#2109164426166d32ea38c405c1e0945d9e6a4eeb" + integrity sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw== dependencies: - kind-of "^6.0.0" + hasown "^2.0.0" -is-date-object@^1.0.1: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -6298,22 +6368,20 @@ is-date-object@^1.0.1: has-tostringtag "^1.0.0" is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + version "0.1.7" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.7.tgz#2727eb61fd789dcd5bdf0ed4569f551d2fe3be33" + integrity sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg== dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.3.tgz#92d27cb3cd311c4977a4db47df457234a13cb306" + integrity sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw== dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" is-docker@^2.0.0: version "2.2.1" @@ -6434,7 +6502,7 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.4: +is-regex@^1.1.4, is-regex@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -6478,18 +6546,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -is-typed-array@^1.1.12: +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== @@ -6582,16 +6639,16 @@ js-sha3@0.5.5: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a" integrity sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA== -js-sha3@0.5.7, js-sha3@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== - js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== +js-sha3@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -6602,14 +6659,6 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg== -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - js-yaml@3.x: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" @@ -6700,11 +6749,14 @@ json-stable-stringify-without-jsonify@^1.0.1: integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json-stable-stringify@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz#e06f23128e0bbe342dc996ed5a19e28b57b580e0" - integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== + version "1.1.0" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.1.0.tgz#43d39c7c8da34bfaf785a61a56808b0def9f747d" + integrity sha512-zfA+5SuwYN2VWqN1/5HZaDzQKLJHaBVMZIIM+wuYjdptkaQsqzDdqjqf+lZZJUuJq1aanHiY8LhH8LmH+qBYJA== dependencies: + call-bind "^1.0.5" + isarray "^2.0.5" jsonify "^0.0.1" + object-keys "^1.1.1" json-stringify-safe@~5.0.1: version "5.0.1" @@ -6756,6 +6808,11 @@ jsonify@^0.0.1: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== + jsonschema@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" @@ -6813,9 +6870,9 @@ keccak@3.0.1: node-gyp-build "^4.2.0" keccak@^3.0.0, keccak@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" - integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" + integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== dependencies: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" @@ -6828,14 +6885,7 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" -keyv@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" - integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== - dependencies: - json-buffer "3.0.1" - -keyv@^4.5.3: +keyv@^4.0.0, keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -6856,12 +6906,7 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: +kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== @@ -7095,14 +7140,6 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -7115,6 +7152,11 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6: resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -7125,6 +7167,11 @@ lodash.isboolean@^3.0.3: resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" @@ -7165,18 +7212,11 @@ lodash@4.17.20: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - log-symbols@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" @@ -7202,12 +7242,12 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -loupe@^2.3.1: - version "2.3.6" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" - integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== +loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== dependencies: - get-func-name "^2.0.0" + get-func-name "^2.0.1" lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" @@ -7430,6 +7470,11 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micro-ftch@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" + integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== + micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7526,13 +7571,6 @@ minimalistic-crypto-utils@^1.0.1: dependencies: brace-expansion "^1.1.7" -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - minimatch@4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" @@ -7554,12 +7592,14 @@ minimatch@^5.0.1, minimatch@~5.1.2: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minimatch@^7.4.3: + version "7.4.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" + integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== + dependencies: + brace-expansion "^2.0.1" -minimist@^1.2.8: +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8, minimist@~1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -7587,6 +7627,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp-promise@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" @@ -7595,16 +7640,9 @@ mkdirp-promise@^5.0.1: mkdirp "*" mkdirp@*: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mkdirp@0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5: version "0.5.6" @@ -7613,6 +7651,16 @@ mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5: dependencies: minimist "^1.2.6" +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mkdirp@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" + integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== + mnemonist@^0.38.0: version "0.38.5" resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" @@ -7620,37 +7668,7 @@ mnemonist@^0.38.0: dependencies: obliterator "^2.0.0" -mocha@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.2.tgz#8e40d198acf91a52ace122cd7599c9ab857b29e6" - integrity sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - -mocha@^10.0.0: +mocha@10.2.0, mocha@^10.0.0, mocha@^10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== @@ -7677,36 +7695,6 @@ mocha@^10.0.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mocha@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" - integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - mocha@^9.0.2: version "9.2.2" resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" @@ -7742,6 +7730,18 @@ mock-fs@^4.1.0: resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== +mock-property@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/mock-property/-/mock-property-1.0.3.tgz#3e37c50a56609d548cabd56559fde3dd8767b10c" + integrity sha512-2emPTb1reeLLYwHxyVx993iYyCHEiRRO+y8NFXFPL5kl5q14sgTK76cXyEKkeKCHeRw35SfdkUJ10Q1KfHuiIQ== + dependencies: + define-data-property "^1.1.1" + functions-have-names "^1.2.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + hasown "^2.0.0" + isarray "^2.0.5" + module-error@^1.0.1, module-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" @@ -7752,11 +7752,6 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -7816,6 +7811,11 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" +nan@^2.17.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" + integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== + nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" @@ -7848,10 +7848,10 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -napi-macros@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" - integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== +napi-macros@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== natural-compare@^1.4.0: version "1.4.0" @@ -7863,7 +7863,7 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.6.0: +neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -7890,18 +7890,10 @@ node-emoji@^1.10.0: dependencies: lodash "^4.17.21" -node-environment-flags@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" - integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== +node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -7914,9 +7906,9 @@ node-fetch@~1.7.1: is-stream "^1.0.1" node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + version "4.7.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.0.tgz#749f0033590b2a89ac8edb5e0775f95f5ae86d15" + integrity sha512-PbZERfeFdrHQOOXiAKOY0VPbykZy90ndPKk0d+CFDegTKmWp1VgOTz2xACVbr1BjCWxrQp68CXtvNsveFhqDJg== nofilter@^3.1.0: version "3.1.0" @@ -8001,22 +7993,17 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.12.2, object-inspect@^1.9.0, object-inspect@~1.12.2: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -object-inspect@^1.12.3: +object-inspect@~1.12.3: version "1.12.3" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== -object-inspect@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - -object-is@^1.0.1: +object-is@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -8024,7 +8011,7 @@ object-is@^1.0.1: call-bind "^1.0.2" define-properties "^1.1.3" -object-keys@^1.0.11, object-keys@^1.1.1: +object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -8041,16 +8028,6 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" @@ -8070,27 +8047,17 @@ object.fromentries@^2.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" -object.getownpropertydescriptors@^2.0.3: - version "2.1.6" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz#5e5c384dd209fa4efffead39e3a0512770ccc312" - integrity sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ== +object.getownpropertydescriptors@^2.1.6: + version "2.1.7" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz#7a466a356cd7da4ba8b9e94ff6d35c3eeab5d56a" + integrity sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g== dependencies: - array.prototype.reduce "^1.0.5" + array.prototype.reduce "^1.0.6" call-bind "^1.0.2" define-properties "^1.2.0" - es-abstract "^1.21.2" + es-abstract "^1.22.1" safe-array-concat "^1.0.0" -object.getownpropertydescriptors@^2.1.1: - version "2.1.5" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" - integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== - dependencies: - array.prototype.reduce "^1.0.5" - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - object.groupby@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" @@ -8199,6 +8166,11 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" +ordinal@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" + integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -8233,13 +8205,6 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -8247,6 +8212,13 @@ p-limit@^3.0.2: dependencies: yocto-queue "^0.1.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -8254,13 +8226,6 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - p-locate@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" @@ -8280,11 +8245,6 @@ p-try@^1.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -8292,7 +8252,7 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-asn1@^5.0.0, parse-asn1@^5.1.5: +parse-asn1@^5.0.0, parse-asn1@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== @@ -8378,7 +8338,7 @@ patch-package@^6.2.2: tmp "^0.0.33" yaml "^1.10.2" -path-browserify@^1.0.0: +path-browserify@^1.0.0, path-browserify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== @@ -8452,6 +8412,11 @@ path@^0.12.7: process "^0.11.1" util "^0.10.3" +pathington@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/pathington/-/pathington-1.1.7.tgz#caf2d2db899a31fea4e81e3657af6acde5171903" + integrity sha512-JxzhUzagDfNIOm4qqwQqP3rWeo7rNNOfIahy4n+3GTEdwXLqw5cJHUR0soSopQtNEv763lzxb6eA2xBllpR8zw== + pathval@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" @@ -8540,6 +8505,13 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== +preprocess@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/preprocess/-/preprocess-3.2.0.tgz#36b3e2c52331fbc6fabb26d4fd5709304b7e3675" + integrity sha512-cO+Rf+Ose/eD+ze8Hxd9p9nS1xT8thYqv8owG/V8+IS/Remd7Z17SvaRK/oJxp08yaM8zb+QTckDKJUul2pk7g== + dependencies: + xregexp "3.1.0" + prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -8548,28 +8520,23 @@ prettier-linter-helpers@^1.0.0: fast-diff "^1.1.2" prettier-plugin-solidity@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" - integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.2.0.tgz#dc620b4fc7708a60687a87cdc803e57a1856b6fd" + integrity sha512-fgxcUZpVAP+LlRfy5JI5oaAkXGkmsje2VJ5krv/YMm+rcTZbIUwFguSw5f+WFuttMjpDm6wB4UL7WVkArEfiVA== dependencies: - "@solidity-parser/parser" "^0.16.0" - semver "^7.3.8" + "@solidity-parser/parser" "^0.16.2" + semver "^7.5.4" solidity-comments-extractor "^0.0.7" -prettier@^2.1.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.2.tgz#c4ea1b5b454d7c4b59966db2e06ed7eec5dfd160" - integrity sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw== - -prettier@^2.8.3: +prettier@^2.1.2, prettier@^2.8.3: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== prettier@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" - integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== + version "3.1.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.0.tgz#c6d16474a5f764ea1a4a373c593b779697744d5e" + integrity sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw== private@^0.1.6, private@^0.1.8: version "0.1.8" @@ -8601,6 +8568,15 @@ promise@^8.0.0: dependencies: asap "~2.0.6" +proper-lockfile@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" + integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== + dependencies: + graceful-fs "^4.2.4" + retry "^0.12.0" + signal-exit "^3.0.2" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -8609,6 +8585,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -8684,6 +8665,14 @@ pull-window@^2.1.4: dependencies: looper "^2.0.0" +pump@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" + integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -8692,20 +8681,20 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== - punycode@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + punycode@^2.1.0, punycode@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.2.0.tgz#2092cc57cd2582c38e4e7e8bb869dc8d3148bc74" - integrity sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== qs@6.11.0: version "6.11.0" @@ -8714,7 +8703,7 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" -qs@^6.4.0: +qs@^6.11.2, qs@^6.4.0: version "6.11.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== @@ -8735,11 +8724,6 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== - querystring@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" @@ -8775,7 +8759,7 @@ range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1, raw-body@^2.4.1: +raw-body@2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== @@ -8785,6 +8769,16 @@ raw-body@2.5.1, raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@2.5.2, raw-body@^2.4.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -8812,10 +8806,10 @@ readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== +readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -8825,16 +8819,16 @@ readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@~1.0.15: +readable-stream@~1.0.15, readable-stream@~1.0.26-4: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== @@ -8844,13 +8838,6 @@ readable-stream@~1.0.15: isarray "0.0.1" string_decoder "~0.10.x" -readdirp@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" - integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== - dependencies: - picomatch "^2.0.4" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -8899,15 +8886,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - regexp.prototype.flags@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" @@ -8969,23 +8947,7 @@ req-from@^2.0.0: dependencies: resolve-from "^3.0.0" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.79.0, request@^2.85.0, request@^2.88.0: +request@^2.79.0, request@^2.85.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -9031,11 +8993,6 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - resolve-alpn@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" @@ -9073,25 +9030,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== - dependencies: - is-core-module "^2.11.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.10.0, resolve@^1.8.1, resolve@~1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.22.4: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.4, resolve@^1.8.1, resolve@~1.22.6: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -9114,18 +9053,16 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - integrity sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w== - dependencies: - through "~2.3.4" - ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -9196,17 +9133,7 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -safe-array-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" - integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-array-concat@^1.0.1: +safe-array-concat@^1.0.0, safe-array-concat@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== @@ -9274,11 +9201,6 @@ sc-istanbul@^0.4.5: which "^1.1.1" wordwrap "^1.0.0" -scrypt-js@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" - integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== - scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" @@ -9311,26 +9233,16 @@ semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^5.7.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^6.3.1: +semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.3.8, semver@^7.5.2, semver@^7.5.4: +semver@^7.3.4, semver@^7.5.1, semver@^7.5.2, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -9428,11 +9340,6 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog== - setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -9501,7 +9408,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -9658,9 +9565,9 @@ solidity-comments-extractor@^0.0.7: integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== solidity-coverage@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.4.tgz#c57a21979f5e86859c5198de9fbae2d3bc6324a5" - integrity sha512-xeHOfBOjdMF6hWTbt42iH4x+7j1Atmrf5OldDPMxI+i/COdExUxszOswD9qqvcBTaLGiOrrpnh9UZjSpt4rBsg== + version "0.8.5" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.5.tgz#64071c3a0c06a0cecf9a7776c35f49edc961e875" + integrity sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ== dependencies: "@ethersproject/abi" "^5.0.9" "@solidity-parser/parser" "^0.16.0" @@ -9674,7 +9581,7 @@ solidity-coverage@^0.8.2: globby "^10.0.1" jsonschema "^1.2.4" lodash "^4.17.15" - mocha "7.1.2" + mocha "10.2.0" node-emoji "^1.10.0" pify "^4.0.1" recursive-readdir "^2.2.2" @@ -9755,9 +9662,9 @@ source-map@~0.2.0: amdefine ">=0.0.4" spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -9776,9 +9683,14 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.12" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" - integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + +split-ca@^1.0.0, split-ca@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" + integrity sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -9792,10 +9704,21 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +ssh2@^1.11.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.14.0.tgz#8f68440e1b768b66942c9e4e4620b2725b3555bb" + integrity sha512-AqzD1UCqit8tbOKoj6ztDDi1ffJZ2rV2SwlgrVVrHPkV5vWqGJOVp5pmtj18PunkPJAuKQsnInyKV+/Nb2bUnA== + dependencies: + asn1 "^0.2.6" + bcrypt-pbkdf "^1.0.2" + optionalDependencies: + cpu-features "~0.0.8" + nan "^2.17.0" + sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -9827,11 +9750,6 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== - stream-to-pull-stream@^1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" @@ -9840,11 +9758,6 @@ stream-to-pull-stream@^1.7.1: looper "^3.0.0" pull-stream "^3.2.3" -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -9859,7 +9772,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.1.1: +string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -9867,15 +9780,6 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -9885,16 +9789,7 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.trim@^1.2.7, string.prototype.trim@~1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.trim@^1.2.8: +string.prototype.trim@^1.2.8, string.prototype.trim@~1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== @@ -9903,15 +9798,6 @@ string.prototype.trim@^1.2.8: define-properties "^1.2.0" es-abstract "^1.22.1" -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trimend@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" @@ -9921,15 +9807,6 @@ string.prototype.trimend@^1.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trimstart@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" @@ -9972,13 +9849,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -10015,23 +9885,11 @@ strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed "1.0.0" -strip-json-comments@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - strip-json-comments@3.1.1, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== - dependencies: - has-flag "^3.0.0" - supports-color@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" @@ -10128,25 +9986,70 @@ tapable@^2.2.0: integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== tape@^4.6.3: - version "4.16.1" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.16.1.tgz#8d511b3a0be1a30441885972047c1dac822fd9be" - integrity sha512-U4DWOikL5gBYUrlzx+J0oaRedm2vKLFbtA/+BRAXboGWpXO7bMP8ddxlq3Cse2bvXFQ0jZMOj6kk3546mvCdFg== + version "4.17.0" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.17.0.tgz#de89f3671ddc5dad178d04c28dc6b0183f42268e" + integrity sha512-KCuXjYxCZ3ru40dmND+oCLsXyuA8hoseu2SS404Px5ouyS0A99v8X/mdiLqsR5MTAyamMBN7PRwt2Dv3+xGIxw== dependencies: + "@ljharb/resumer" "~0.0.1" + "@ljharb/through" "~2.3.9" call-bind "~1.0.2" deep-equal "~1.1.1" - defined "~1.0.0" + defined "~1.0.1" dotignore "~0.1.2" for-each "~0.3.3" glob "~7.2.3" has "~1.0.3" inherits "~2.0.4" is-regex "~1.1.4" - minimist "~1.2.6" - object-inspect "~1.12.2" - resolve "~1.22.1" - resumer "~0.0.0" - string.prototype.trim "~1.2.6" - through "~2.3.8" + minimist "~1.2.8" + mock-property "~1.0.0" + object-inspect "~1.12.3" + resolve "~1.22.6" + string.prototype.trim "~1.2.8" + +tar-fs@~1.16.3: + version "1.16.3" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" + integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw== + dependencies: + chownr "^1.0.1" + mkdirp "^0.5.1" + pump "^1.0.0" + tar-stream "^1.1.2" + +tar-fs@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" + integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.0.0" + +tar-stream@^1.1.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar-stream@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" tar@^4.0.2: version "4.4.19" @@ -10161,6 +10064,16 @@ tar@^4.0.2: safe-buffer "^5.2.1" yallist "^3.1.1" +template-file@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/template-file/-/template-file-6.0.1.tgz#ce4d1f48e56d637cc94bb97ec205e6e035bbb2a5" + integrity sha512-02hOa1psJUOsahWfx8w3p40CCulA2/InNFFPh5xLq5rUUm2XTzvmtOn/SXV+KZaq7ylG58SYSnT4yW3y/Smn4w== + dependencies: + "@blakek/deep" "^2.2.0" + glob "^7.1.6" + mkdirp "^1.0.4" + p-limit "^4.0.0" + test-value@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" @@ -10218,7 +10131,7 @@ through2@^2.0.3: readable-stream "~2.3.6" xtend "~4.0.1" -through@~2.3.4, through@~2.3.8: +"through@>=2.2.7 <3": version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== @@ -10247,6 +10160,11 @@ tmp@0.1.0: dependencies: rimraf "^2.6.3" +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -10294,7 +10212,7 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@^2.3.3, tough-cookie@~2.5.0: +tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -10352,6 +10270,14 @@ ts-generator@^0.1.1: resolve "^1.8.1" ts-essentials "^1.0.0" +ts-morph@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-19.0.0.tgz#43e95fb0156c3fe3c77c814ac26b7d0be2f93169" + integrity sha512-D6qcpiJdn46tUqV45vr5UGM2dnIEuTGNxVhg0sk5NX11orcouwj6i1bMqZIz2mZTZB1Hcgy7C3oEVhAT+f6mbQ== + dependencies: + "@ts-morph/common" "~0.20.0" + code-block-writer "^12.0.0" + ts-node@^10.1.0: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -10432,7 +10358,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@^4.0.0, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -10552,6 +10478,11 @@ typescript@^4.6.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + typewise-core@^1.2, typewise-core@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" @@ -10604,12 +10535,17 @@ underscore@1.9.1: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + undici@^5.14.0: - version "5.22.1" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.22.1.tgz#877d512effef2ac8be65e695f3586922e1a57d7b" - integrity sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw== + version "5.27.2" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.27.2.tgz#a270c563aea5b46cc0df2550523638c95c5d4411" + integrity sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ== dependencies: - busboy "^1.6.0" + "@fastify/busboy" "^2.0.0" union-value@^1.0.0: version "1.0.1" @@ -10627,9 +10563,9 @@ universalify@^0.1.0: integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unorm@^1.3.3: version "1.6.0" @@ -10679,12 +10615,12 @@ url-set-query@^1.0.0: integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== + version "0.11.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" + integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== dependencies: - punycode "1.3.2" - querystring "0.2.0" + punycode "^1.4.1" + qs "^6.11.2" use@^3.1.0: version "3.1.1" @@ -10709,15 +10645,17 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== util.promisify@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" - integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== + version "1.1.2" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.2.tgz#02b3dbadbb80071eee4c43aed58747afdfc516db" + integrity sha512-PBdZ03m1kBnQ5cjjO0ZvJMJS+QsbyIcFwi4hY4U76OQsCO9JrOYjbCFgIF76ccFg9xnJo7ZHPkqyj1GqmdS7MA== dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" + call-bind "^1.0.2" + define-properties "^1.2.0" for-each "^0.3.3" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.1" + has-proto "^1.0.1" + has-symbols "^1.0.3" + object.getownpropertydescriptors "^2.1.6" + safe-array-concat "^1.0.0" util@^0.10.3: version "0.10.4" @@ -10731,11 +10669,6 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== - uuid@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -11040,27 +10973,15 @@ web3-utils@1.2.11: underscore "1.9.1" utf8 "3.0.0" -web3-utils@^1.0.0-beta.31, web3-utils@^1.3.4: - version "1.8.1" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.1.tgz#f2f7ca7eb65e6feb9f3d61056d0de6bbd57125ff" - integrity sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ== - dependencies: - bn.js "^5.2.1" - ethereum-bloom-filters "^1.0.6" - ethereumjs-util "^7.1.0" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -web3-utils@^1.3.6: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578" - integrity sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg== +web3-utils@^1.0.0-beta.31, web3-utils@^1.3.4, web3-utils@^1.3.6: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" + integrity sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ== dependencies: + "@ethereumjs/util" "^8.1.0" bn.js "^5.2.1" ethereum-bloom-filters "^1.0.6" - ethereumjs-util "^7.1.0" + ethereum-cryptography "^2.1.2" ethjs-unit "0.1.6" number-to-bn "1.7.0" randombytes "^2.1.0" @@ -11137,11 +11058,6 @@ which-module@^1.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== -which-module@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" - integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== - which-typed-array@^1.1.11, which-typed-array@^1.1.13: version "1.1.13" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" @@ -11153,25 +11069,6 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.13: gopd "^1.0.1" has-tostringtag "^1.0.0" -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" - -which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - which@2.0.2, which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -11179,12 +11076,12 @@ which@2.0.2, which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== +which@^1.1.1, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: - string-width "^1.0.2 || 2" + isexe "^2.0.0" window-size@^0.2.0: version "0.2.0" @@ -11192,9 +11089,9 @@ window-size@^0.2.0: integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== wordwrap@^1.0.0: version "1.0.0" @@ -11219,15 +11116,6 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -11310,10 +11198,10 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: parse-headers "^2.0.0" xtend "^4.0.0" -xmlhttprequest@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== +xregexp@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-3.1.0.tgz#14d8461e0bdd38224bfee5039a0898fc42fcd336" + integrity sha512-4Y1x6DyB8xRoxosooa6PlGWqmmSKatbzhrftZ7Purmm4B8R4qIEJG1A2hZsdz5DhmIqS0msC0I7KEq93GphEVg== xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" @@ -11332,11 +11220,6 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -11362,14 +11245,6 @@ yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@13.1.2, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs-parser@20.2.4: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" @@ -11388,15 +11263,6 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-unparser@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" - integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== - dependencies: - flat "^4.1.0" - lodash "^4.17.15" - yargs "^13.3.0" - yargs-unparser@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" @@ -11407,22 +11273,6 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@13.3.2, yargs@^13.3.0: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - yargs@16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" @@ -11466,7 +11316,26 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== + +zksync-ethers@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.0.0.tgz#2d0bb9a98ad1198957038f7669a50b10ef96bc3c" + integrity sha512-zPowwK/2wG3YqIlKNtRfzpMnHMnWSa5wFsfDrxKFgLjbA3VvuHl4mFCFUxMapsroGyG619+zt71HKM1jyNpSmQ== + dependencies: + ethers "~5.7.0" + zksync-web3@^0.14.3: - version "0.14.3" - resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.14.3.tgz#64ac2a16d597464c3fc4ae07447a8007631c57c9" - integrity sha512-hT72th4AnqyLW1d5Jlv8N2B/qhEnl2NePK2A3org7tAa24niem/UAaHMkEvmWI3SF9waYUPtqAtjpf+yvQ9zvQ== + version "0.14.4" + resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.14.4.tgz#0b70a7e1a9d45cc57c0971736079185746d46b1f" + integrity sha512-kYehMD/S6Uhe1g434UnaMN+sBr9nQm23Ywn0EUP5BfQCsbjcr3ORuS68PosZw8xUTu3pac7G6YMSnNHk+fwzvg== + +zksync-web3@^0.15.4: + version "0.15.5" + resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.15.5.tgz#aabe379464963ab573e15948660a709f409b5316" + integrity sha512-97gB7OKJL4spegl8fGO54g6cvTd/75G6yFWZWEa2J09zhjTrfqabbwE/GwiUJkFQ5BbzoH4JaTlVz1hoYZI+DQ== + dependencies: + ethers "~5.7.0" diff --git a/zksync/.eslintrc b/zksync/.eslintrc deleted file mode 100644 index c84119c89..000000000 --- a/zksync/.eslintrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": ["@matterlabs/eslint-config-typescript"], - "rules": { - "no-multiple-empty-lines": ["error", { "max": 1 }], - "@typescript-eslint/no-namespace": "off", - "import/no-named-as-default-member": "off", - "import/namespace": "off", - "import/no-unresolved": "off", - "import/order": "off" - } -} diff --git a/zksync/.gitignore b/zksync/.gitignore deleted file mode 100644 index 9042230ab..000000000 --- a/zksync/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/build -/artifacts -/artifacts-zk -/cache -/cache-zk -/typechain -node_modules -./contracts/DS_Store -yarn-debug.log* -yarn-error.log* diff --git a/zksync/.markdownlintignore b/zksync/.markdownlintignore deleted file mode 100644 index 3c3629e64..000000000 --- a/zksync/.markdownlintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/zksync/.markdownlintrc b/zksync/.markdownlintrc deleted file mode 100644 index d6bb9e817..000000000 --- a/zksync/.markdownlintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "default": true, - "header-increment": false, - "no-duplicate-header": false, - "no-inline-html": false, - "line-length": false, - "fenced-code-language": false, - "no-multiple-blanks": false -} diff --git a/zksync/.nvmrc b/zksync/.nvmrc deleted file mode 100644 index 6aab9b43f..000000000 --- a/zksync/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v18.18.0 diff --git a/zksync/.prettierignore b/zksync/.prettierignore deleted file mode 100644 index 2b6d3a683..000000000 --- a/zksync/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -artifacts-zk -cache-zk -node_modules diff --git a/zksync/.prettierrc.js b/zksync/.prettierrc.js deleted file mode 100644 index 020982998..000000000 --- a/zksync/.prettierrc.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - ...require("@matterlabs/prettier-config"), - plugins: ["prettier-plugin-solidity"], - overrides: [ - { - files: "*.sol", - options: { - bracketSpacing: false, - printWidth: 120, - singleQuote: false, - tabWidth: 4, - useTabs: false, - }, - }, - ], -}; diff --git a/zksync/.solhint.json b/zksync/.solhint.json deleted file mode 100644 index 5329702df..000000000 --- a/zksync/.solhint.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "solhint:recommended", - "rules": { - "state-visibility": "off", - "func-visibility": ["warn", { "ignoreConstructors": true }], - "var-name-mixedcase": "off", - "avoid-call-value": "off", - "no-empty-blocks": "off", - "not-rely-on-time": "off", - "avoid-low-level-calls": "off", - "no-inline-assembly": "off", - "const-name-snakecase": "off", - "no-complex-fallback": "off", - "reason-string": "off", - "func-name-mixedcase": "off", - "no-unused-vars": "off", - "max-states-count": "off", - "compiler-version": ["warn", "^0.8.0"] - } -} diff --git a/zksync/.solhintignore b/zksync/.solhintignore deleted file mode 100644 index b77edd4cc..000000000 --- a/zksync/.solhintignore +++ /dev/null @@ -1,2 +0,0 @@ -cache-zk -node_modules diff --git a/zksync/yarn.lock b/zksync/yarn.lock deleted file mode 100644 index 4482a1724..000000000 --- a/zksync/yarn.lock +++ /dev/null @@ -1,5470 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@babel/code-frame@^7.0.0": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== - dependencies: - "@babel/highlight" "^7.22.13" - chalk "^2.4.2" - -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@balena/dockerignore@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" - integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== - -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - -"@chainsafe/persistent-merkle-tree@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" - integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/persistent-merkle-tree@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" - integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/ssz@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" - -"@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" - integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== - -"@eslint/eslintrc@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" - integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.52.0": - version "8.52.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.52.0.tgz#78fe5f117840f69dc4a353adf9b9cd926353378c" - integrity sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA== - -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/contracts@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" - integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== - dependencies: - "@ethersproject/abi" "^5.7.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - -"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": - version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" - integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/solidity@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" - integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/units@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" - integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/wallet@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@humanwhocodes/config-array@^0.11.13": - version "0.11.13" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" - integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== - dependencies: - "@humanwhocodes/object-schema" "^2.0.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" - integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@matterlabs/eslint-config-typescript@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@matterlabs/eslint-config-typescript/-/eslint-config-typescript-1.1.2.tgz#a9be4e56aedf298800f247c5049fc412f8b301a7" - integrity sha512-AhiWJQr+MSE3RVfgp5XwGoMK7kNSKh6a18+T7hkNJtyycP0306I6IGmuFA5ZVbcakGb+K32fQWzepSkrNCTAGg== - -"@matterlabs/hardhat-zksync-deploy@^0.6.5": - version "0.6.5" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-0.6.5.tgz#fe56bf30850e71c8d328ac1a06a100c1a0af6e3e" - integrity sha512-EZpvn8pDslfO3UA2obT8FOi5jsHhxYS5ndIR7tjL2zXKbvkbpoJR5rgKoGTJJm0riaCud674sQcxMOybVQ+2gg== - dependencies: - "@matterlabs/hardhat-zksync-solc" "0.4.2" - chalk "4.1.2" - ts-morph "^19.0.0" - -"@matterlabs/hardhat-zksync-solc@0.3.17", "@matterlabs/hardhat-zksync-solc@^0.3.15": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.3.17.tgz#72f199544dc89b268d7bfc06d022a311042752fd" - integrity sha512-aZgQ0yfXW5xPkfuEH1d44ncWV4T2LzKZd0VVPo4PL5cUrYs2/II1FaEDp5zsf3FxOR1xT3mBsjuSrtJkk4AL8Q== - dependencies: - "@nomiclabs/hardhat-docker" "^2.0.0" - chalk "4.1.2" - dockerode "^3.3.4" - -"@matterlabs/hardhat-zksync-solc@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.2.tgz#64121082e88c5ab22eb4e9594d120e504f6af499" - integrity sha512-6NFWPSZiOAoo7wNuhMg4ztj7mMEH+tLrx09WuCbcURrHPijj/KxYNsJD6Uw5lapKr7G8H7SQISGid1/MTXVmXQ== - dependencies: - "@nomiclabs/hardhat-docker" "^2.0.0" - chalk "4.1.2" - dockerode "^3.3.4" - fs-extra "^11.1.1" - proper-lockfile "^4.1.2" - semver "^7.5.1" - -"@matterlabs/hardhat-zksync-verify@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.2.0.tgz#a0c6b897202057873355b680244f72f573d86a97" - integrity sha512-iUwxhPlNk+HWe+UadLqQzdDb2fammbKYoz8wqVuyr9jygFUf8JNPLWDZOS0KCQgRn/dmT22+i9nSREOg66bAHA== - dependencies: - "@matterlabs/hardhat-zksync-solc" "0.3.17" - axios "^1.4.0" - chalk "4.1.2" - dockerode "^3.3.4" - -"@matterlabs/prettier-config@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@matterlabs/prettier-config/-/prettier-config-1.0.3.tgz#3e2eb559c0112bbe9671895f935700dad2a15d38" - integrity sha512-JW7nHREPqEtjBWz3EfxLarkmJBD8vi7Kx/1AQ6eBZnz12eHc1VkOyrc6mpR5ogTf0dOUNXFAfZut+cDe2dn4kQ== - -"@metamask/eth-sig-util@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" - integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== - dependencies: - ethereumjs-abi "^0.6.8" - ethereumjs-util "^6.2.1" - ethjs-util "^0.1.6" - tweetnacl "^1.0.3" - tweetnacl-util "^0.15.1" - -"@noble/hashes@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" - integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== - -"@noble/hashes@~1.1.1": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" - integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== - -"@noble/secp256k1@1.6.3", "@noble/secp256k1@~1.6.0": - version "1.6.3" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" - integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nomicfoundation/ethereumjs-block@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz#6f89664f55febbd723195b6d0974773d29ee133d" - integrity sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - -"@nomicfoundation/ethereumjs-blockchain@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz#80e0bd3535bfeb9baa29836b6f25123dab06a726" - integrity sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-ethash" "3.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz#4702d82df35b07b5407583b54a45bf728e46a2f0" - integrity sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.1" - crc-32 "^1.2.0" - -"@nomicfoundation/ethereumjs-ethash@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz#65ca494d53e71e8415c9a49ef48bc921c538fc41" - integrity sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - bigint-crypto-utils "^3.0.23" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz#f35681e203363f69ce2b3d3bf9f44d4e883ca1f1" - integrity sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ== - dependencies: - "@ethersproject/providers" "^5.7.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/ethereumjs-rlp@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz#0b30c1cf77d125d390408e391c4bb5291ef43c28" - integrity sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ== - -"@nomicfoundation/ethereumjs-statemanager@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz#8824a97938db4471911e2d2f140f79195def5935" - integrity sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" - -"@nomicfoundation/ethereumjs-trie@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz#662c55f6b50659fd4b22ea9f806a7401cafb7717" - integrity sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz#7629dc2036b4a33c34e9f0a592b43227ef4f0c7d" - integrity sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w== - dependencies: - "@chainsafe/ssz" "^0.9.2" - "@ethersproject/providers" "^5.7.2" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz#530cda8bae33f8b5020a8f199ed1d0a2ce48ec89" - integrity sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA== - dependencies: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-vm@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz#7d035e0993bcad10716c8b36e61dfb87fa3ca05f" - integrity sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-blockchain" "7.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-evm" "2.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-statemanager" "2.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/hardhat-chai-matchers@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz#72a2e312e1504ee5dd73fe302932736432ba96bc" - integrity sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@types/chai-as-promised" "^7.1.3" - chai-as-promised "^7.1.1" - deep-eql "^4.0.1" - ordinal "^1.0.3" - -"@nomicfoundation/hardhat-ethers@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.4.tgz#6f0df2424e687e26d6574610de7a36bd69485cc1" - integrity sha512-k9qbLoY7qn6C6Y1LI0gk2kyHXil2Tauj4kGzQ8pgxYXIGw8lWn8tuuL72E11CrlKaXRUvOgF0EXrv/msPI2SbA== - dependencies: - debug "^4.1.1" - lodash.isequal "^4.5.0" - -"@nomicfoundation/hardhat-verify@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-1.1.1.tgz#6a433d777ce0172d1f0edf7f2d3e1df14b3ecfc1" - integrity sha512-9QsTYD7pcZaQFEA3tBb/D/oCStYDiEVDN7Dxeo/4SCyHRSm86APypxxdOMEPlGmXsAvd+p1j/dTODcpxb8aztA== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - lodash.clonedeep "^4.5.0" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz#83a7367342bd053a76d04bbcf4f373fef07cf760" - integrity sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw== - -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz#1225f7da647ae1ad25a87125664704ecc0af6ccc" - integrity sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA== - -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz#dbc052dcdfd50ae50fd5ae1788b69b4e0fa40040" - integrity sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg== - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz#e6b2eea633995b557e74e881d2a43eab4760903d" - integrity sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ== - -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz#af81107f5afa794f19988a368647727806e18dc4" - integrity sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w== - -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz#6877e1da1a06a9f08446070ab6e0a5347109f868" - integrity sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw== - -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz#bb6cd83a0c259eccef4183796b6329a66cf7ebd9" - integrity sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg== - -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz#9d4bca1cc9a1333fde985675083b0b7d165f6076" - integrity sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw== - -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz#0db5bfc6aa952bea4098d8d2c8947b4e5c4337ee" - integrity sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw== - -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz#2e0f39a2924dcd77db6b419828595e984fabcb33" - integrity sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA== - -"@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz#e5ddc43ad5c0aab96e5054520d8e16212e125f50" - integrity sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg== - optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.0" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.0" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.0" - -"@nomiclabs/hardhat-docker@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-docker/-/hardhat-docker-2.0.2.tgz#ae964be17951275a55859ff7358e9e7c77448846" - integrity sha512-XgGEpRT3wlA1VslyB57zyAHV+oll8KnV1TjwnxxC1tpAL04/lbdwpdO5KxInVN8irMSepqFpsiSkqlcnvbE7Ng== - dependencies: - dockerode "^2.5.8" - fs-extra "^7.0.1" - node-fetch "^2.6.0" - -"@nomiclabs/hardhat-ethers@^2.0.0": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.2.tgz#812d48929c3bf8fe840ec29eab4b613693467679" - integrity sha512-NLDlDFL2us07C0jB/9wzvR0kuLivChJWCXTKcj3yqjZqMoYp7g7wwS157F70VHx/+9gHIBGzak5pKDwG8gEefA== - -"@nomiclabs/hardhat-etherscan@^3.1.7": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" - integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - fs-extra "^7.0.1" - lodash "^4.17.11" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - -"@nomiclabs/hardhat-solpp@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-solpp/-/hardhat-solpp-2.0.1.tgz#04039b3745b8d2b48c9b8bec6509e9785631aaba" - integrity sha512-aWYvB91GPJcnye4Ph26Jd9BfBNNisI1iRNSbHB2i09OpxucSHAPMvvqTfWDN1HE5EMjqlTJ2rQLdlDcYqQxPJw== - dependencies: - fs-extra "^7.0.1" - solpp "^0.11.5" - -"@openzeppelin/contracts-upgradeable@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.6.0.tgz#1bf55f230f008554d4c6fe25eb165b85112108b0" - integrity sha512-5OnVuO4HlkjSCJO165a4i2Pu1zQGzMs//o54LPrwUgxvEO2P3ax1QuaSI0cEHHTveA77guS0PnNugpR2JMsPfA== - -"@openzeppelin/contracts@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.6.0.tgz#c91cf64bc27f573836dba4122758b4743418c1b3" - integrity sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg== - -"@pkgr/utils@^2.3.1": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" - integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== - dependencies: - cross-spawn "^7.0.3" - fast-glob "^3.3.0" - is-glob "^4.0.3" - open "^9.1.0" - picocolors "^1.0.0" - tslib "^2.6.0" - -"@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== - -"@scure/bip32@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.0.tgz#dea45875e7fbc720c2b4560325f1cf5d2246d95b" - integrity sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q== - dependencies: - "@noble/hashes" "~1.1.1" - "@noble/secp256k1" "~1.6.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" - integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== - dependencies: - "@noble/hashes" "~1.1.1" - "@scure/base" "~1.1.0" - -"@sentry/core@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" - integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/hub@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" - integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== - dependencies: - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/minimal@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" - integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sentry/node@^5.18.1": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" - integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== - dependencies: - "@sentry/core" "5.30.0" - "@sentry/hub" "5.30.0" - "@sentry/tracing" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - cookie "^0.4.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/tracing@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" - integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/types@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" - integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== - -"@sentry/utils@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" - integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== - dependencies: - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@solidity-parser/parser@^0.16.0": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" - integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@ts-morph/common@~0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.20.0.tgz#3f161996b085ba4519731e4d24c35f6cba5b80af" - integrity sha512-7uKjByfbPpwuzkstL3L5MQyuXPSKdoNG93Fmi2JoDcTf3pEP731JdRFAduRVkOs8oqxPsXKA+ScrWkdQ8t/I+Q== - dependencies: - fast-glob "^3.2.12" - minimatch "^7.4.3" - mkdirp "^2.1.6" - path-browserify "^1.0.1" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@typechain/ethers-v5@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz#cd3ca1590240d587ca301f4c029b67bfccd08810" - integrity sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw== - dependencies: - ethers "^5.0.2" - -"@types/bn.js@^4.11.3": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - -"@types/chai-as-promised@^7.1.3": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.6.tgz#3b08cbe1e7206567a480dc6538bade374b19e4e1" - integrity sha512-cQLhk8fFarRVZAXUQV1xEnZgMoPxqKojBvRkqPCKPQCzEhpbbSKl1Uu75kDng7k5Ln6LQLUmNBjLlFthCgm1NA== - dependencies: - "@types/chai" "*" - -"@types/chai-as-promised@^7.1.4": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" - integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== - dependencies: - "@types/chai" "*" - -"@types/chai@*", "@types/chai@^4.2.21": - version "4.3.4" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" - integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== - -"@types/json-schema@^7.0.12": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/lru-cache@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" - integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== - -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - -"@types/mocha@^8.2.3": - version "8.2.3" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" - integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== - -"@types/node@*": - version "18.11.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" - integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== - dependencies: - "@types/node" "*" - -"@types/prettier@^2.1.1": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" - integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== - -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" - -"@types/resolve@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" - integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== - dependencies: - "@types/node" "*" - -"@types/semver@^7.5.0": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" - integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== - -"@typescript-eslint/eslint-plugin@^6.7.4": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz#06abe4265e7c82f20ade2dcc0e3403c32d4f148b" - integrity sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.8.0" - "@typescript-eslint/type-utils" "6.8.0" - "@typescript-eslint/utils" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.4" - natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/parser@^6.7.4": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.8.0.tgz#bb2a969d583db242f1ee64467542f8b05c2e28cb" - integrity sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg== - dependencies: - "@typescript-eslint/scope-manager" "6.8.0" - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/typescript-estree" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz#5cac7977385cde068ab30686889dd59879811efd" - integrity sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g== - dependencies: - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" - -"@typescript-eslint/type-utils@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz#50365e44918ca0fd159844b5d6ea96789731e11f" - integrity sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g== - dependencies: - "@typescript-eslint/typescript-estree" "6.8.0" - "@typescript-eslint/utils" "6.8.0" - debug "^4.3.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/types@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.8.0.tgz#1ab5d4fe1d613e3f65f6684026ade6b94f7e3ded" - integrity sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ== - -"@typescript-eslint/typescript-estree@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz#9565f15e0cd12f55cf5aa0dfb130a6cb0d436ba1" - integrity sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg== - dependencies: - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/visitor-keys" "6.8.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/utils@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.8.0.tgz#d42939c2074c6b59844d0982ce26a51d136c4029" - integrity sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.8.0" - "@typescript-eslint/types" "6.8.0" - "@typescript-eslint/typescript-estree" "6.8.0" - semver "^7.5.4" - -"@typescript-eslint/visitor-keys@6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz#cffebed56ae99c45eba901c378a6447b06be58b8" - integrity sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg== - dependencies: - "@typescript-eslint/types" "6.8.0" - eslint-visitor-keys "^3.4.1" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - -JSONStream@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" - integrity sha512-mn0KSip7N4e0UDPZHnqDsHECo5uGQrixQKnAskOM1BIB8hd7QKbd6il8IPRPudPHOeHiECoCFqhyMaRO9+nWyA== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - 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" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.4.1: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== - -acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - -adm-zip@^0.4.16: - version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" - integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.12.4, ajv@^6.12.6: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.1: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -antlr4@^4.11.0: - version "4.13.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" - integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== - -antlr4@~4.8.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.8.0.tgz#f938ec171be7fc2855cd3a533e87647185b32b6a" - integrity sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg== - -antlr4ts@^0.5.0-alpha.4: - version "0.5.0-alpha.4" - resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" - integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-back@^1.0.3, array-back@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" - integrity sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw== - dependencies: - typical "^2.6.0" - -array-back@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" - integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== - dependencies: - typical "^2.6.1" - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.findlastindex@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - -asn1@^0.2.4: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -ast-parents@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" - integrity sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA== - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -axios@^0.21.1: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - -axios@^1.4.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.1.tgz#11fbaa11fc35f431193a9564109c88c1f27b585f" - integrity sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -big-integer@^1.6.44: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - -bigint-crypto-utils@^3.0.23: - version "3.1.8" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d" - integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw== - dependencies: - bigint-mod-arith "^3.1.0" - -bigint-mod-arith@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz#658e416bc593a463d97b59766226d0a3021a76b1" - integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bl@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" - integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -blakejs@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" - integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== - -bn-str-256@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/bn-str-256/-/bn-str-256-1.9.1.tgz#898cebee70a3edc3968f97b4cebbc4771025aa82" - integrity sha512-u3muv3WO5sYv9nUQsPnDGLg731yNt/MOlKPK5pmBVqClcl7tY97tyfKxw8ed44HVrpi+7dkgJgQpbXP47a3GoQ== - dependencies: - decimal.js-light "^2.5.0" - lodash "^4.17.11" - -bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -browser-level@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" - integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.1" - module-error "^1.0.2" - run-parallel-limit "^1.1.0" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buildcheck@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.3.tgz#70451897a95d80f7807e68fc412eb2e7e35ff4d5" - integrity sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA== - -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== - dependencies: - run-applescript "^5.0.0" - -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== - dependencies: - function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -case@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" - integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== - -catering@^2.1.0, catering@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" - integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== - -cbor@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" - integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== - dependencies: - nofilter "^3.1.0" - -chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" - integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - dependencies: - check-error "^1.0.2" - -chai@^4.3.4: - version "4.3.7" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" - integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^4.1.2" - get-func-name "^2.0.0" - loupe "^2.3.1" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== - -chokidar@3.5.3, chokidar@^3.4.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chownr@^1.0.1, chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -classic-level@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" - integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.0" - module-error "^1.0.1" - napi-macros "~2.0.0" - node-gyp-build "^4.3.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -code-block-writer@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770" - integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -command-line-args@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" - integrity sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA== - dependencies: - array-back "^2.0.0" - find-replace "^1.0.3" - typical "^2.6.1" - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -commander@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" - integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== - -commander@^2.19.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - -commander@~9.4.1: - version "9.4.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" - integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -concat-stream@~1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cosmiconfig@^8.0.0: - version "8.3.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" - integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== - dependencies: - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - path-type "^4.0.0" - -cpu-features@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.4.tgz#0023475bb4f4c525869c162e4108099e35bf19d8" - integrity sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A== - dependencies: - buildcheck "0.0.3" - nan "^2.15.0" - -crc-32@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -debug@^3.2.6, debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -decimal.js-light@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" - integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== - -deep-eql@^4.0.1, deep-eql@^4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" - integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== - dependencies: - type-detect "^4.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== - dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" - -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -docker-modem@^1.0.8: - version "1.0.9" - resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-1.0.9.tgz#a1f13e50e6afb6cf3431b2d5e7aac589db6aaba8" - integrity sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw== - dependencies: - JSONStream "1.3.2" - debug "^3.2.6" - readable-stream "~1.0.26-4" - split-ca "^1.0.0" - -docker-modem@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-3.0.6.tgz#8c76338641679e28ec2323abb65b3276fb1ce597" - integrity sha512-h0Ow21gclbYsZ3mkHDfsYNDqtRhXS8fXr51bU0qr1dxgTMJj0XufbzX+jhNOvA8KuEEzn6JbvLVhXyv+fny9Uw== - dependencies: - debug "^4.1.1" - readable-stream "^3.5.0" - split-ca "^1.0.1" - ssh2 "^1.11.0" - -dockerode@^2.5.8: - version "2.5.8" - resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-2.5.8.tgz#1b661e36e1e4f860e25f56e0deabe9f87f1d0acc" - integrity sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw== - dependencies: - concat-stream "~1.6.2" - docker-modem "^1.0.8" - tar-fs "~1.16.3" - -dockerode@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-3.3.4.tgz#875de614a1be797279caa9fe27e5637cf0e40548" - integrity sha512-3EUwuXnCU+RUlQEheDjmBE0B7q66PV9Rw5NiH1sXwINq0M9c5ERP9fxgkw36ZHOtzf4AGEEYySnkx/sACC9EgQ== - dependencies: - "@balena/dockerignore" "^1.0.2" - docker-modem "^3.0.0" - tar-fs "~2.0.1" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dotenv@^16.0.3: - version "16.0.3" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== - -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@^5.12.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -enquirer@^2.3.0: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -entities@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" - integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.12" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" - -es-set-tostringtag@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" - integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== - dependencies: - get-intrinsic "^1.2.2" - has-tostringtag "^1.0.0" - hasown "^2.0.0" - -es-shim-unscopables@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" - integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== - dependencies: - hasown "^2.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-import-resolver-typescript@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz#7b983680edd3f1c5bce1a5829ae0bc2d57fe9efa" - integrity sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg== - dependencies: - debug "^4.3.4" - enhanced-resolve "^5.12.0" - eslint-module-utils "^2.7.4" - fast-glob "^3.3.1" - get-tsconfig "^4.5.0" - is-core-module "^2.11.0" - is-glob "^4.0.3" - -eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" - integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.14.2" - -eslint-plugin-prettier@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz#a3b399f04378f79f066379f544e42d6b73f11515" - integrity sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg== - dependencies: - prettier-linter-helpers "^1.0.0" - synckit "^0.8.5" - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint@^8.51.0: - version "8.52.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.52.0.tgz#d0cd4a1fac06427a61ef9242b9353f36ea7062fc" - integrity sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.52.0" - "@humanwhocodes/config-array" "^0.11.13" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== - dependencies: - "@types/pbkdf2" "^3.0.0" - "@types/secp256k1" "^4.0.1" - blakejs "^1.1.0" - browserify-aes "^1.2.0" - bs58check "^2.1.2" - create-hash "^1.2.0" - create-hmac "^1.1.7" - hash.js "^1.1.7" - keccak "^3.0.0" - pbkdf2 "^3.0.17" - randombytes "^2.1.0" - safe-buffer "^5.1.2" - scrypt-js "^3.0.0" - secp256k1 "^4.0.1" - setimmediate "^1.0.5" - -ethereum-cryptography@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz#74f2ac0f0f5fe79f012c889b3b8446a9a6264e6d" - integrity sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ== - dependencies: - "@noble/hashes" "1.1.2" - "@noble/secp256k1" "1.6.3" - "@scure/bip32" "1.1.0" - "@scure/bip39" "1.1.0" - -ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== - dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" - -ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" - integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== - dependencies: - "@ethersproject/abi" "5.7.0" - "@ethersproject/abstract-provider" "5.7.0" - "@ethersproject/abstract-signer" "5.7.0" - "@ethersproject/address" "5.7.0" - "@ethersproject/base64" "5.7.0" - "@ethersproject/basex" "5.7.0" - "@ethersproject/bignumber" "5.7.0" - "@ethersproject/bytes" "5.7.0" - "@ethersproject/constants" "5.7.0" - "@ethersproject/contracts" "5.7.0" - "@ethersproject/hash" "5.7.0" - "@ethersproject/hdnode" "5.7.0" - "@ethersproject/json-wallets" "5.7.0" - "@ethersproject/keccak256" "5.7.0" - "@ethersproject/logger" "5.7.0" - "@ethersproject/networks" "5.7.1" - "@ethersproject/pbkdf2" "5.7.0" - "@ethersproject/properties" "5.7.0" - "@ethersproject/providers" "5.7.2" - "@ethersproject/random" "5.7.0" - "@ethersproject/rlp" "5.7.0" - "@ethersproject/sha2" "5.7.0" - "@ethersproject/signing-key" "5.7.0" - "@ethersproject/solidity" "5.7.0" - "@ethersproject/strings" "5.7.0" - "@ethersproject/transactions" "5.7.0" - "@ethersproject/units" "5.7.0" - "@ethersproject/wallet" "5.7.0" - "@ethersproject/web" "5.7.1" - "@ethersproject/wordlists" "5.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" - integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2, fast-diff@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - -fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-replace@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" - integrity sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA== - dependencies: - array-back "^1.0.4" - test-value "^2.1.0" - -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - -flat-cache@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" - integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== - dependencies: - flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.2.9: - version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" - integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== - -follow-redirects@^1.12.1, follow-redirects@^1.14.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -follow-redirects@^1.15.0: - version "1.15.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" - integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== - -get-intrinsic@^1.0.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== - dependencies: - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-stdin@~9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" - integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== - -get-stream@^6.0.0, get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -get-tsconfig@^4.5.0: - version "4.7.2" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.2.tgz#0dcd6fb330391d46332f4c6c1bf89a6514c2ddce" - integrity sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A== - dependencies: - resolve-pkg-maps "^1.0.0" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.2, glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - 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" - -glob@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -glob@~8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -globals@^13.19.0: - version "13.23.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" - integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -hardhat-typechain@^0.3.3: - version "0.3.5" - resolved "https://registry.yarnpkg.com/hardhat-typechain/-/hardhat-typechain-0.3.5.tgz#8e50616a9da348b33bd001168c8fda9c66b7b4af" - integrity sha512-w9lm8sxqTJACY+V7vijiH+NkPExnmtiQEjsV9JKD1KgMdVk2q8y+RhvU/c4B7+7b1+HylRUCxpOIvFuB3rE4+w== - -hardhat@=2.16.0: - version "2.16.0" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.16.0.tgz#c5611d433416b31f6ce92f733b1f1b5236ad6230" - integrity sha512-7VQEJPQRAZdtrYUZaU9GgCpP3MBNy/pTdscARNJQMWKj5C+R7V32G5uIZKIqZ4QiqXa6CBfxxe+G+ahxUbHZHA== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-blockchain" "7.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-evm" "2.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-statemanager" "2.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - "@nomicfoundation/ethereumjs-vm" "7.0.1" - "@nomicfoundation/solidity-analyzer" "^0.1.0" - "@sentry/node" "^5.18.1" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "^5.1.0" - abort-controller "^3.0.0" - adm-zip "^0.4.16" - aggregate-error "^3.0.0" - ansi-escapes "^4.3.0" - chalk "^2.4.2" - chokidar "^3.4.0" - ci-info "^2.0.0" - debug "^4.1.1" - enquirer "^2.3.0" - env-paths "^2.2.0" - ethereum-cryptography "^1.0.3" - ethereumjs-abi "^0.6.8" - find-up "^2.1.0" - fp-ts "1.19.3" - fs-extra "^7.0.1" - glob "7.2.0" - immutable "^4.0.0-rc.12" - io-ts "1.10.4" - keccak "^3.0.2" - lodash "^4.17.11" - mnemonist "^0.38.0" - mocha "^10.0.0" - p-map "^4.0.0" - raw-body "^2.4.1" - resolve "1.17.0" - semver "^6.3.0" - solc "0.7.3" - source-map-support "^0.5.13" - stacktrace-parser "^0.1.10" - tsort "0.0.1" - undici "^5.14.0" - uuid "^8.3.2" - ws "^7.4.6" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== - dependencies: - get-intrinsic "^1.2.2" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== - dependencies: - function-bind "^1.1.2" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.13, ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^5.2.0, ignore@^5.2.4, ignore@~5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -immutable@^4.0.0-rc.12: - version "4.2.2" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.2.tgz#2da9ff4384a4330c36d4d1bc88e90f9e0b0ccd16" - integrity sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og== - -import-fresh@^3.2.1, import-fresh@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.1.tgz#c76ec81007875bc44d544ff7a11a55d12294102d" - integrity sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ== - -internal-slot@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== - dependencies: - get-intrinsic "^1.2.2" - hasown "^2.0.0" - side-channel "^1.0.4" - -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== - dependencies: - fp-ts "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== - -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -js-sdsl@^4.1.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" - integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== - -js-sha3@0.8.0, js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -jsonc-parser@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -keccak@^3.0.0, keccak@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" - integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -keyv@^4.5.3: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== - optionalDependencies: - graceful-fs "^4.1.9" - -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - -level@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" - integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== - dependencies: - browser-level "^1.0.1" - classic-level "^1.2.0" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -linkify-it@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" - integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== - dependencies: - uc.micro "^1.0.1" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - -lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -loupe@^2.3.1: - version "2.3.6" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" - integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== - dependencies: - get-func-name "^2.0.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -markdown-it@13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" - integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== - dependencies: - argparse "^2.0.1" - entities "~3.0.1" - linkify-it "^4.0.1" - mdurl "^1.0.1" - uc.micro "^1.0.5" - -markdownlint-cli@^0.33.0: - version "0.33.0" - resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.33.0.tgz#703af1234c32c309ab52fcd0e8bc797a34e2b096" - integrity sha512-zMK1oHpjYkhjO+94+ngARiBBrRDEUMzooDHBAHtmEIJ9oYddd9l3chCReY2mPlecwH7gflQp1ApilTo+o0zopQ== - dependencies: - commander "~9.4.1" - get-stdin "~9.0.0" - glob "~8.0.3" - ignore "~5.2.4" - js-yaml "^4.1.0" - jsonc-parser "~3.2.0" - markdownlint "~0.27.0" - minimatch "~5.1.2" - run-con "~1.2.11" - -markdownlint@~0.27.0: - version "0.27.0" - resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.27.0.tgz#9dabf7710a4999e2835e3c68317f1acd0bc89049" - integrity sha512-HtfVr/hzJJmE0C198F99JLaeada+646B5SaG2pVoEakLFI6iRGsvMqrnnrflq8hm1zQgwskEgqSnhDW11JBp0w== - dependencies: - markdown-it "13.0.1" - -mcl-wasm@^0.7.1: - version "0.7.9" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" - integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== - -memory-level@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" - integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== - dependencies: - abstract-level "^1.0.0" - functional-red-black-tree "^1.0.1" - module-error "^1.0.1" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== - dependencies: - brace-expansion "^1.1.7" - -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1, minimatch@~5.1.2: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^7.4.3: - version "7.4.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" - integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0, minimist@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== - -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -mkdirp@^0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mkdirp@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" - integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== - -mnemonist@^0.38.0: - version "0.38.5" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" - integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== - dependencies: - obliterator "^2.0.0" - -mocha@^10.0.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mocha@^9.0.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" - integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.3" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "4.2.1" - ms "2.1.3" - nanoid "3.3.1" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -module-error@^1.0.1, module-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nan@^2.15.0, nan@^2.16.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - -nanoid@3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== - -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - -napi-macros@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" - integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-fetch@^2.6.0: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== - -nofilter@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" - integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - -object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - -object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.groupby@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - -object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -obliterator@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" - integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -open@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== - dependencies: - default-browser "^4.0.0" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - is-wsl "^2.2.0" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -ordinal@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" - integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -path-browserify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - -path-parse@^1.0.6, path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -pbkdf2@^3.0.17: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pluralize@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" - integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier-plugin-solidity@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" - integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== - dependencies: - "@solidity-parser/parser" "^0.16.0" - semver "^7.3.8" - solidity-comments-extractor "^0.0.7" - -prettier@^2.1.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.2.tgz#c4ea1b5b454d7c4b59966db2e06ed7eec5dfd160" - integrity sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw== - -prettier@^2.8.3: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -prettier@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" - integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proper-lockfile@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" - integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== - dependencies: - graceful-fs "^4.2.4" - retry "^0.12.0" - signal-exit "^3.0.2" - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -pump@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" - integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -queue-microtask@^1.2.2, queue-microtask@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -raw-body@^2.4.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - 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.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@~1.0.26-4: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^2.0.0, require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.10.0, resolve@^1.8.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.22.4: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^2.2.8: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.2.3: - version "2.2.7" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" - integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== - dependencies: - bn.js "^5.2.0" - -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" - -run-con@~1.2.11: - version "1.2.12" - resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.2.12.tgz#51c319910e45a3bd71ee773564a89d96635c8c64" - integrity sha512-5257ILMYIF4RztL9uoZ7V9Q97zHtNHn5bN3NobeAnzB1P3ASLgg8qocM2u+R18ttp+VEM78N2LK8XcNVtnSRrg== - dependencies: - deep-extend "^0.6.0" - ini "~3.0.0" - minimist "^1.2.8" - strip-json-comments "~3.1.1" - -run-parallel-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" - integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== - dependencies: - queue-microtask "^1.2.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -scrypt-js@3.0.1, scrypt-js@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== - dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.8, semver@^7.5.1, semver@^7.5.2, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-function-length@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" - integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== - dependencies: - define-data-property "^1.1.1" - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -set-function-name@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== - dependencies: - define-data-property "^1.0.1" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -solhint@^3.6.2: - version "3.6.2" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.6.2.tgz#2b2acbec8fdc37b2c68206a71ba89c7f519943fe" - integrity sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ== - dependencies: - "@solidity-parser/parser" "^0.16.0" - ajv "^6.12.6" - antlr4 "^4.11.0" - ast-parents "^0.0.1" - chalk "^4.1.2" - commander "^10.0.0" - cosmiconfig "^8.0.0" - fast-diff "^1.2.0" - glob "^8.0.3" - ignore "^5.2.4" - js-yaml "^4.1.0" - lodash "^4.17.21" - pluralize "^8.0.0" - semver "^7.5.2" - strip-ansi "^6.0.1" - table "^6.8.1" - text-table "^0.2.0" - optionalDependencies: - prettier "^2.8.3" - -solidity-comments-extractor@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" - integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== - -solpp@^0.11.5: - version "0.11.5" - resolved "https://registry.yarnpkg.com/solpp/-/solpp-0.11.5.tgz#e5f38b5acc952e1cc2e3871d490fdbed910938dd" - integrity sha512-LjzCGMrTDXtera2C4mbQGZSpBznP+o3/82L2CneAAMNbm+t4xPsvfrgJkIaY+IZ5YLrB8IXn7cYthwHMKvAWnQ== - dependencies: - antlr4 "~4.8.0" - axios "^0.21.1" - bn-str-256 "^1.9.1" - commander "^2.19.0" - ethereumjs-util "^6.0.0" - lodash "^4.17.11" - mz "^2.7.0" - resolve "^1.10.0" - semver "^5.6.0" - -source-map-support@^0.5.13: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -split-ca@^1.0.0, split-ca@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" - integrity sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ== - -ssh2@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.11.0.tgz#ce60186216971e12f6deb553dcf82322498fe2e4" - integrity sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw== - dependencies: - asn1 "^0.2.4" - bcrypt-pbkdf "^1.0.2" - optionalDependencies: - cpu-features "~0.0.4" - nan "^2.16.0" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A== - dependencies: - is-hex-prefixed "1.0.0" - -strip-json-comments@3.1.1, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -synckit@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" - integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== - dependencies: - "@pkgr/utils" "^2.3.1" - tslib "^2.5.0" - -table@^6.8.0, table@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" - integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - -tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -tar-fs@~1.16.3: - version "1.16.3" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" - integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw== - dependencies: - chownr "^1.0.1" - mkdirp "^0.5.1" - pump "^1.0.0" - tar-stream "^1.1.2" - -tar-fs@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" - integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.0.0" - -tar-stream@^1.1.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" - -tar-stream@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -test-value@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" - integrity sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w== - dependencies: - array-back "^1.0.3" - typical "^2.6.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - -tmp@0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -ts-api-utils@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" - integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== - -ts-essentials@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" - integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== - -ts-essentials@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" - integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== - -ts-generator@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" - integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== - dependencies: - "@types/mkdirp" "^0.5.2" - "@types/prettier" "^2.1.1" - "@types/resolve" "^0.0.8" - chalk "^2.4.1" - glob "^7.1.2" - mkdirp "^0.5.1" - prettier "^2.1.2" - resolve "^1.8.1" - ts-essentials "^1.0.0" - -ts-morph@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-19.0.0.tgz#43e95fb0156c3fe3c77c814ac26b7d0be2f93169" - integrity sha512-D6qcpiJdn46tUqV45vr5UGM2dnIEuTGNxVhg0sk5NX11orcouwj6i1bMqZIz2mZTZB1Hcgy7C3oEVhAT+f6mbQ== - dependencies: - "@ts-morph/common" "~0.20.0" - code-block-writer "^12.0.0" - -ts-node@^10.1.0: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -tsconfig-paths@^3.14.2: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.5.0, tslib@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== - -tweetnacl-util@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - -tweetnacl@^0.14.3: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -typechain@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-4.0.3.tgz#e8fcd6c984676858c64eeeb155ea783a10b73779" - integrity sha512-tmoHQeXZWHxIdeLK+i6dU0CU0vOd9Cndr3jFTZIMzak5/YpFZ8XoiYpTZcngygGBqZo+Z1EUmttLbW9KkFZLgQ== - dependencies: - command-line-args "^4.0.7" - debug "^4.1.1" - fs-extra "^7.0.0" - js-sha3 "^0.8.0" - lodash "^4.17.15" - ts-essentials "^7.0.1" - ts-generator "^0.1.1" - -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - -typescript@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" - integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== - -typical@^2.6.0, typical@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" - integrity sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg== - -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -undici@^5.14.0: - version "5.25.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.25.2.tgz#17ddc3e8ab3c77e473ae1547f3f2917a05da2820" - integrity sha512-tch8RbCfn1UUH1PeVCXva4V8gDpGAud/w0WubD6sHC46vYQ3KDxL+xv1A2UxK0N6jrVedutuPHxe1XIoqerwMw== - dependencies: - busboy "^1.6.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-typed-array@^1.1.11, which-typed-array@^1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which@2.0.2, which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== - -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@^7.4.6: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zksync-web3@^0.15.4: - version "0.15.4" - resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.15.4.tgz#5991435593e591aa5f7ee68567315be07b478710" - integrity sha512-6CEpRBbF4nGwRYSF3KvPGqg2aNJFYTl8AR+cejBnC2Uyu1v3NYSkmkXXVuMGupJ7HIQR1aTqFEDsUFPyO/bL0Q==