diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 0a3aa4659..000000000
--- a/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["es2015", "stage-2", "stage-3", "env"]
-}
diff --git a/.env.example b/.env.example
new file mode 100644
index 000000000..de753c1b6
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,100 @@
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+##############################
+# Private Key Configurations #
+##############################=
+# The key to a pre-funded deployer address
+DEPLOYER_PRIVATE_KEY=
+
+############################
+# FiatToken Configurations #
+############################
+# The ERC20 name of the FiatToken.
+TOKEN_NAME=USDC
+
+# The ERC20 symbol of the FiatToken.
+TOKEN_SYMBOL=USDC
+
+# The fiat currency that that FiatToken represents.
+TOKEN_CURRENCY=USD
+
+# The ERC20 decimals for the FiatToken.
+TOKEN_DECIMALS=6
+
+# [OPTIONAL] The address to a deployed FiatTokenProxy contract.
+# FIAT_TOKEN_PROXY_ADDRESS=
+
+# [OPTIONAL] The address to a deployed FiatToken implementation contract.
+# FIAT_TOKEN_IMPLEMENTATION_ADDRESS=
+
+# The address of the FiatTokenProxy's admin.
+PROXY_ADMIN_ADDRESS=
+
+# The address of the FiatToken's owner.
+OWNER_ADDRESS=
+
+# The address of the MasterMinter's owner.
+MASTER_MINTER_OWNER_ADDRESS=
+
+# [OPTIONAL] The address of the FiatToken's pauser. Defaults to the owner address.
+# PAUSER_ADDRESS=
+
+# [OPTIONAL] The address of the FiatToken's blacklister. Defaults to the owner address.
+# BLACKLISTER_ADDRESS=
+
+# [OPTIONAL] The address to which locked funds are sent to. Only applicable for version 2 -> 2.1 upgrades. Defaults to the owner address.
+# LOST_AND_FOUND_ADDRESS=
+
+##########################
+# Network Configurations #
+##########################
+# [OPTIONAL] The URL to a mainnet JSON-RPC node.
+# MAINNET_RPC_URL=
+
+# [OPTIONAL] The URL to a testnet JSON-RPC node.
+# TESTNET_RPC_URL=
+
+# The percentage to multiply gas usage estimations by (eg. 200 to double the estimation). Defaults to 130.
+GAS_MULTIPLIER=110
+
+################################
+# Celo Specific Configurations #
+################################
+
+# [OPTIONAL] The address to a deployed FiatTokenCelo implementation contract.
+# FIAT_TOKEN_CELO_IMPLEMENTATION_ADDRESS=
+
+# [OPTIONAL] The address to a deployed FiatTokenProxy contract for FiatTokenCeloV2_2. Required for Celo Fee Adapter deployment.
+# FIAT_TOKEN_CELO_PROXY_ADDRESS=
+
+# [OPTIONAL] The address of the Fee Adapter Proxy's admin. Required for Celo Fee Adapter deployment.
+# FEE_ADAPTER_PROXY_ADMIN_ADDRESS=
+
+# [OPTIONAL] The number of decimals to scale the USDC contract to. Required for Celo Fee Adapter deployment.
+# FEE_ADAPTER_DECIMALS=
+
+################################
+# Miscellaneous Configurations #
+################################
+# The file name from which to read the list of addresses to blacklist
+BLACKLIST_FILE_NAME=blacklist.remote.json
+
+# [OPTIONAL] The API key to an Etherscan flavor block explorer.
+# ETHERSCAN_KEY=
+
+# [OPTIONAL] The number of runs the Solidity optimizers should perform. Defaults to 10000000.
+# OPTIMIZER_RUNS=
diff --git a/.eslintignore b/.eslintignore
index 60388cc6b..b2cec2eeb 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,4 +1,18 @@
-.DS_Store
+.idea/
+**/.DS_Store
+
+artifacts/
+cache/
+@types/generated/
+
node_modules/
+yarn-error.log
+
coverage/
-@types/generated/
\ No newline at end of file
+coverage.json
+
+verification_artifacts/
+
+blacklist.*.json
+
+LICENSE
diff --git a/.eslintrc.js b/.eslintrc.js
index fc1855f93..6580bb89e 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
module.exports = {
root: true,
env: {
diff --git a/.gitattributes b/.gitattributes
index 6e1727aa2..3c2122c8a 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1 @@
@types/generated/**/* linguist-generated=true
-
diff --git a/.githooks/pre-commit b/.githooks/pre-commit
deleted file mode 100755
index f906c3977..000000000
--- a/.githooks/pre-commit
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to verify what is about to be committed.
-# Called by "git commit" with no arguments. The hook should
-# exit with non-zero status after issuing an appropriate message if
-# it wants to stop the commit.
-#
-# To enable this hook, rename this file to "pre-commit".
-
-root_dir=$(git rev-parse --git-dir)
-root_dir=$(cd $root_dir > /dev/null && cd .. > /dev/null && pwd -P)
-
-cd $root_dir
-
-yarn precommit
diff --git a/.github/composite-actions/setup-ci/action.yml b/.github/composite-actions/setup-ci/action.yml
new file mode 100644
index 000000000..1a55f4a67
--- /dev/null
+++ b/.github/composite-actions/setup-ci/action.yml
@@ -0,0 +1,52 @@
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: Setup CI
+runs:
+ using: composite
+ steps:
+ - name: Install Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: "20.9.0"
+
+ - name: Install Foundry
+ uses: foundry-rs/foundry-toolchain@v1
+
+ - name: Update submodules
+ run: git submodule update --init --recursive
+ shell: bash
+
+ - name: Install Yarn
+ run: npm install -g yarn@1.22.19
+ shell: bash
+
+ - name: Get Yarn cache directory path
+ id: yarn-cache-dir-path
+ run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
+ shell: bash
+
+ - name: Retrieve cache
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+ key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-
+
+ - name: Install packages & Setup repository
+ run: yarn install --frozen-lockfile
+ shell: bash
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..e734a1f7c
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,11 @@
+## Summary
+
+## Detail
+
+## Testing
+
+## Documentation
+
+---
+
+**Requested Reviewers:** @mention
diff --git a/.github/resources/coverage-report-template.md b/.github/resources/coverage-report-template.md
new file mode 100644
index 000000000..e01f08e4e
--- /dev/null
+++ b/.github/resources/coverage-report-template.md
@@ -0,0 +1,33 @@
+
+
+## Coverage Report
+
+Commit: [{{short_commit_sha}}]({{commit_link}})
+
+| Type | Coverage |
+| ------------------------- | ------------------------------------- |
+| Total Statements Coverage | {{total_statements_coverage_percent}} |
+| Total Branches Coverage | {{total_branches_coverage_percent}} |
+| Total Functions Coverage | {{total_functions_coverage_percent}} |
+| Total Lines Coverage | {{total_lines_coverage_percent}} |
+
+
+Details
+{{files_coverage_table}}
+
diff --git a/.github/workflows/bytecode-verification.yml b/.github/workflows/bytecode-verification.yml
new file mode 100644
index 000000000..57ae74687
--- /dev/null
+++ b/.github/workflows/bytecode-verification.yml
@@ -0,0 +1,37 @@
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: Bridged USDC deployment - Bytecode Verification
+on:
+ pull_request:
+ paths:
+ - "**/verification_artifacts/input.json"
+
+jobs:
+ bytecode-verification:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v4
+
+ - name: Setup CI Environment
+ uses: ./.github/composite-actions/setup-ci
+
+ - name: Compile contracts
+ run: yarn compile
+
+ - name: Run Verification
+ run: yarn hardhat run scripts/verifyBridgedTokenBytecode.ts --network mainnet
diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml
new file mode 100644
index 000000000..b9e3dc294
--- /dev/null
+++ b/.github/workflows/check-pr.yml
@@ -0,0 +1,50 @@
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: Check PR
+on:
+ workflow_run:
+ workflows: [CI]
+ types: [completed]
+
+permissions:
+ checks: write
+ contents: write
+ actions: read
+
+jobs:
+ post_run_hardhat_tests:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Download test results
+ uses: actions/download-artifact@v4
+ with:
+ pattern: junit-report-*
+ run-id: ${{ github.event.workflow_run.id }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Publish combined test report
+ uses: mikepenz/action-junit-report@v4
+ with:
+ check_name: upload_test_results
+ job_summary: true
+ detailed_summary: true
+ commit: ${{ github.event.workflow_run.head_sha }}
+ report_paths: "./junit-report-*/junit.xml"
+
+ release-sbom:
+ if: github.event.workflow_run.event == 'push'
+ uses: circlefin/circle-public-github-workflows/.github/workflows/attach-release-assets.yaml@v1
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 000000000..a38929d29
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,98 @@
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: CI
+on:
+ push:
+ branches: [master]
+ pull_request:
+
+permissions: read-all
+
+# Celo USDC contracts violate Spurious Dragon with existing configs, so
+# we need to lower the number of runs to decrease the contract size.
+env:
+ OPTIMIZER_RUNS: 81250
+
+jobs:
+ run_ci_tests:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v4
+
+ - name: Setup CI Environment
+ uses: ./.github/composite-actions/setup-ci
+
+ - name: Compile contracts
+ run: yarn compile
+
+ - name: Run static checks
+ run: yarn static-check
+
+ - name: Run size check
+ run: yarn contract-size
+
+ - name: Run forge tests
+ run: forge test -vvv
+
+ - name: Generate gas report
+ run: yarn gas-report
+ env:
+ ENABLE_GAS_REPORTER: true
+
+ run_hardhat_tests:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ test-groups:
+ - grep: "FiatTokenV1:.*"
+ - grep: "FiatTokenV1_1:.*"
+ - grep: "FiatTokenV2:.*"
+ - grep: "FiatTokenV2_1:.*"
+ - grep: "FiatTokenV2_2:.*"
+ - grep: "FiatTokenV1:.*|FiatTokenV1_1:.*|FiatTokenV2:.*|FiatTokenV2_1:.*|FiatTokenV2_2:.*|gas costs"
+ invert: true
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v4
+
+ - name: Setup CI Environment
+ uses: ./.github/composite-actions/setup-ci
+
+ - name: Compile contracts
+ run: yarn compile
+
+ - name: Run hardhat tests
+ run: HARDHAT_TEST_GREP='${{ matrix.test-groups.grep }}' HARDHAT_TEST_INVERT='${{ matrix.test-groups.invert }}' yarn test
+
+ - name: Upload test results to artifacts
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: junit-report-${{ hashFiles('report/junit.xml') }}
+ path: report/junit.xml
+
+ scan:
+ if: github.event_name == 'pull_request'
+ uses: circlefin/circle-public-github-workflows/.github/workflows/pr-scan.yaml@v1
+ permissions:
+ pull-requests: write
+ contents: read
+ with:
+ allow-reciprocal-licenses: false
+
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 000000000..0601549db
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,60 @@
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: Coverage
+on:
+ pull_request:
+ types: [labeled]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ run_coverage:
+ runs-on: ubuntu-latest
+ if: ${{ github.event.label.name == 'needs_coverage' }}
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v4
+
+ - name: Setup CI Environment
+ uses: ./.github/composite-actions/setup-ci
+
+ - name: Compile contracts
+ run: yarn compile
+
+ - name: Run coverage
+ run: yarn coverage
+
+ - name: Report coverage to PR
+ id: report-coverage
+ uses: sidx1024/report-nyc-coverage-github-action@v1.2.7
+ with:
+ coverage_file: "coverage/coverage-summary.json"
+ base_coverage_file: ""
+ comment_template_file: ".github/resources/coverage-report-template.md"
+
+ - name: Check coverage
+ if: |
+ fromJSON(steps.report-coverage.outputs.total_lines_coverage_percent_raw) < 100 ||
+ fromJSON(steps.report-coverage.outputs.total_branches_coverage_percent_raw) < 98 ||
+ fromJSON(steps.report-coverage.outputs.total_statements_coverage_percent_raw) < 100 ||
+ fromJSON(steps.report-coverage.outputs.total_functions_coverage_percent_raw) < 100
+ uses: actions/github-script@v7
+ with:
+ script: |
+ core.setFailed('Test coverage is under the threshold')
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 000000000..2a2fc6fbd
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,27 @@
+# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
+#
+# You can adjust the behavior by modifying this file.
+# For more information, see:
+# https://github.com/actions/stale
+name: Mark stale issues and pull requests
+
+on:
+ schedule:
+ - cron: '45 5 * * *'
+
+jobs:
+ stale:
+
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+
+ steps:
+ - uses: actions/stale@v5
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ stale-issue-message: 'Stale issue message'
+ stale-pr-message: 'Stale pull request message'
+ stale-issue-label: 'no-issue-activity'
+ stale-pr-label: 'no-pr-activity'
diff --git a/.gitignore b/.gitignore
index bbfbcc8a7..bf0ca40d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,19 +1,17 @@
-.DS_Store
-build/
-node_modules/
-coverage/
-coverage.json
-package-lock.json
.idea/
+.env*
+!.env.example
+**/.DS_Store
+
artifacts/
-contracts/.DS_Store
-token.json
-credentials.json
-echidna/
-validate/apikey.infura
-ganache-blockchain-log.txt
-.coverage_artifacts
-.coverage_contracts
-yarn-error.log
+broadcast/
+cache/
@types/generated/
-config.js
+
+node_modules/
+yarn-error.log
+
+coverage/
+coverage.json
+
+blacklist.*.json
diff --git a/.gitmodules b/.gitmodules
index bf1389467..281fbe379 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,4 @@
-[submodule "echidna"]
- path = echidna
- url = git@github.com:trailofbits/echidna.git
+[submodule "lib/forge-std"]
+ path = lib/forge-std
+ url = https://github.com/foundry-rs/forge-std
+ ignore = dirty
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 000000000..be539834c
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+. "$(dirname -- "$0")/_/husky.sh"
+
+yarn precommit
diff --git a/.licenseignore b/.licenseignore
new file mode 100644
index 000000000..a042cc07b
--- /dev/null
+++ b/.licenseignore
@@ -0,0 +1,43 @@
+pkg:npm/pako
+pkg:npm/highlightjs-solidity
+pkg:npm/ethereum-ens
+pkg:npm/interface-ipld-format
+pkg:npm/multiformats
+pkg:npm/%40ethereumjs/rlp@4.0.1
+pkg:npm/%40ethereumjs/tx@3.3.2
+pkg:npm/%40ethereumjs/util@7.1.5
+pkg:npm/%40ethereumjs/util@8.1.0
+pkg:npm/%40nomicfoundation/ethereumjs-block@5.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-blockchain@7.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-ethash@3.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-evm@2.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-rlp@5.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-statemanager@2.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-trie@6.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-tx@5.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-util@9.0.2
+pkg:npm/%40nomicfoundation/ethereumjs-vm@7.0.2
+pkg:npm/ghost-testrpc@0.0.2
+pkg:npm/sha.js@2.4.11
+pkg:npm/sprintf-js@1.0.3
+pkg:npm/web3@1.10.1
+pkg:npm/web3-bzz@1.10.1
+pkg:npm/web3-core@1.10.1
+pkg:npm/web3-core-helpers@1.10.1
+pkg:npm/web3-core-method@1.10.1
+pkg:npm/web3-core-promievent@1.10.1
+pkg:npm/web3-core-requestmanager@1.10.1
+pkg:npm/web3-core-subscriptions@1.10.1
+pkg:npm/web3-eth@1.10.1
+pkg:npm/web3-eth-abi@1.10.1
+pkg:npm/web3-eth-accounts@1.10.1
+pkg:npm/web3-eth-contract@1.10.1
+pkg:npm/web3-eth-ens@1.10.1
+pkg:npm/web3-eth-iban@1.10.1
+pkg:npm/web3-eth-personal@1.10.1
+pkg:npm/web3-net@1.10.1
+pkg:npm/web3-providers-http@1.10.1
+pkg:npm/web3-providers-ipc@1.10.1
+pkg:npm/web3-providers-ws@1.10.1
+pkg:npm/web3-shh@1.10.1
+pkg:npm/web3-utils@1.10.1
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 000000000..805b5a4e0
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+v20.9.0
diff --git a/.prettierignore b/.prettierignore
index e5b68009b..e9f332716 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,8 +1,20 @@
-.DS_Store
+.idea/
+**/.DS_Store
+
+artifacts/
+cache/
+broadcast/
+@types/generated/
+
node_modules/
+lib/
+yarn-error.log
+
coverage/
coverage.json
-@types/generated/
-build/
-.coverage_contracts/
-.coverage_artifacts/
+
+verification_artifacts/
+
+blacklist.*.json
+
+LICENSE
diff --git a/.prettierrc b/.prettierrc
index a5c35f86b..1444ed799 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -25,6 +25,12 @@
"options": {
"proseWrap": "always"
}
+ },
+ {
+ "files": ".github/pull_request_template.md",
+ "options": {
+ "proseWrap": "never"
+ }
}
]
}
diff --git a/.solcover.js b/.solcover.js
index eb8380cd8..278739156 100644
--- a/.solcover.js
+++ b/.solcover.js
@@ -1,10 +1,22 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
module.exports = {
- providerOptions: {
- port: 8555,
- seed: "TestRPC is awesome!",
- total_accounts: 15,
- default_balance_ether: 1000000,
- },
skipFiles: ["test/", "v2/upgrader/"],
- copyPackages: ["openzeppelin-solidity", "zos-lib"],
+ istanbulReporter: ["text", "json-summary"],
};
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index fbd73d11b..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: node_js
-node_js:
- - 12
-
-before_install:
- - curl -o- -L https://yarnpkg.com/install.sh | bash
- - export PATH="$HOME/.yarn/bin:$PATH"
-
-install:
- - yarn install --frozen-lockfile
-
-script:
- - yarn compile && yarn typechain
- - yarn ganache & sleep 5 && yarn test
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index eddb75a46..5ca1223d8 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -2,6 +2,7 @@
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
- "juanblanco.solidity"
+ "juanblanco.solidity",
+ "ymotongpoo.licenser"
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6720ec14e..d6834c1d9 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,8 +1,4 @@
{
- "files.exclude": {
- "**/.DS_Store": true,
- "**/node_modules/": true
- },
"solidity.packageDefaultDependenciesContractsDirectory": "",
"solidity.packageDefaultDependenciesDirectory": "node_modules",
"solidity.formatter": "none",
@@ -21,9 +17,16 @@
},
"[solidity]": {
"editor.tabSize": 4,
- "editor.formatOnSave": true
+ "editor.formatOnSave": true,
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.formatOnSave": true
- }
+ },
+ "typescript.tsdk": "node_modules/typescript/lib",
+ "licenser.license": "Custom",
+ "licenser.customHeader": "Copyright @YEAR@ Circle Internet Group, Inc. All rights reserved.\n\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.",
+ "licenser.useSingleLineStyle": false,
+ "files.autoSave": "onFocusChange",
+ "solidity.compileUsingRemoteVersion": "v0.6.12+commit.27d51765"
}
diff --git a/@types/AnyFiatTokenV2Instance.d.ts b/@types/AnyFiatTokenV2Instance.d.ts
new file mode 100644
index 000000000..e22dfc000
--- /dev/null
+++ b/@types/AnyFiatTokenV2Instance.d.ts
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { FiatTokenV2Instance } from "./generated/FiatTokenV2";
+import { FiatTokenV2_1Instance } from "./generated/FiatTokenV2_1";
+import { FiatTokenV2_2Instance } from "./generated/FiatTokenV2_2";
+import { FiatTokenCeloV2_2Instance } from "./generated/FiatTokenCeloV2_2";
+
+export interface FiatTokenV2_2InstanceExtended extends FiatTokenV2_2Instance {
+ permit?: typeof FiatTokenV2Instance.permit;
+ transferWithAuthorization?: typeof FiatTokenV2Instance.transferWithAuthorization;
+ receiveWithAuthorization?: typeof FiatTokenV2Instance.receiveWithAuthorization;
+ cancelAuthorization?: typeof FiatTokenV2Instance.cancelAuthorization;
+}
+
+export interface FiatTokenCeloV2_2InstanceExtended
+ extends FiatTokenCeloV2_2Instance {
+ permit?: typeof FiatTokenV2Instance.permit;
+ transferWithAuthorization?: typeof FiatTokenV2Instance.transferWithAuthorization;
+ receiveWithAuthorization?: typeof FiatTokenV2Instance.receiveWithAuthorization;
+ cancelAuthorization?: typeof FiatTokenV2Instance.cancelAuthorization;
+ mint: typeof FiatTokenV2Instance.mint;
+}
+
+export type AnyFiatTokenV2Instance =
+ | FiatTokenV2Instance
+ | FiatTokenV2_1Instance
+ | FiatTokenV2_2InstanceExtended
+ | FiatTokenCeloV2_2InstanceExtended;
diff --git a/@types/TransactionRawLog.d.ts b/@types/TransactionRawLog.d.ts
index f19751270..8e8a2e389 100644
--- a/@types/TransactionRawLog.d.ts
+++ b/@types/TransactionRawLog.d.ts
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
export interface TransactionRawLog {
logIndex: number;
transactionIndex: number;
diff --git a/@types/ipfs-only-hash.d.ts b/@types/ipfs-only-hash.d.ts
new file mode 100644
index 000000000..46ccdcab1
--- /dev/null
+++ b/@types/ipfs-only-hash.d.ts
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+declare module "ipfs-only-hash";
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..1d04f7160
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,54 @@
+# Changelog
+
+## 2.2.0, Celo variant (2024-04-08)
+
+- Add `ICeloGasToken` and `IFiatTokenFeeAdapter` per Celo documentation
+- Add `FiatTokenFeeAdapterProxy` and `FiatTokenFeeAdapterV1` to support USDC as
+ gas on Celo
+- Implement `debitGasFees` and `creditGasFees` in `FiatTokenCeloV2_2`
+
+## 2.2.0 (2023-11-09)
+
+- Add ERC-1271 signature validation support to EIP-2612 and EIP-3009 functions
+- Combine the balance state and the blacklist state for an address in a
+ `balanceAndBlacklistStates` map to reduce gas usage
+- Update `DOMAIN_SEPARATOR` to be a dynamic value
+- Remove `notBlacklisted` modifiers for `approve`, `increaseAllowance`,
+ `decreaseAllowance` and `permit`
+- Enable bypassing `TIMESTAMP` opcode in `permit` by using `uint256.max`
+
+## 2.1.1 (2021-06-03)
+
+- Add the multi-issuer minter contracts from the `multi-issuer` branch
+
+## 2.1.0 (2021-02-17)
+
+- Move locked USDC to a "lost and found" address and blacklists itself so that
+ accidental sends will no longer be possible
+- Conform to EIP-3009 in FiatToken
+ - Add `receiveWithAuthorization`
+ - Remove `approveWithAuthorization`, `increaseAllowanceWithAuthorization` and
+ `decreaseAllowanceWithAuthorization`
+
+## 2.0.0 (2020-07-30)
+
+- Add support for EIP-2612 in FiatToken
+- Add `transferWithAuthorization`, `approveWithAuthorization`,
+ `increaseAllowanceWithAuthorization`, `decreaseAllowanceWithAuthorization` to
+ enable ETH-less transactions
+- Add `increaseAllowance` and `decreaseAllowance` to mitigate the
+ multi-withdrawal attack vulnerability in ERC-20 `approve` function
+- Update Solidity version to `0.6.12`
+
+## 1.1.0 (2020-05-27)
+
+- Add Rescuable functionalities to FiatToken
+- Update Solidity version to `0.6.8`
+- Remove `ifAdmin` modifier from admin() and implementation() in FiatTokenProxy
+
+## 1.0.0 (2018-07-24)
+
+- Create ERC-20 compliant FiatToken contract
+- Add Ownable, Pausable and Blacklistable functionalities to FiatToken
+- Create FiatTokenProxy contracts based on Zeppelinos's Unstructured-Storage
+ Proxy pattern
diff --git a/Dockerfile.ganache b/Dockerfile.ganache
deleted file mode 100644
index 347028e72..000000000
--- a/Dockerfile.ganache
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM node:12-alpine
-
-RUN npm i npm@latest -g \
- && npm install -g ganache-cli@^6.9.1
-
-ENTRYPOINT ["ganache-cli"]
diff --git a/Dockerfile.truffle b/Dockerfile.truffle
deleted file mode 100644
index 985cafe14..000000000
--- a/Dockerfile.truffle
+++ /dev/null
@@ -1,8 +0,0 @@
-FROM node:12-alpine
-
-RUN npm i npm@latest -g \
- && npm install -g truffle@^5.1.24 \
- && npm install -g ganache-cli@^6.9.1
-
-ENTRYPOINT ["truffle"]
-CMD ["--help"]
diff --git a/LICENSE b/LICENSE
index 702f20e7b..7a4a3ea24 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,19 +1,202 @@
-Copyright (c) 2018-2020 CENTRE SECZ
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/README.md b/README.md
index 8cecf7b71..385dfebec 100644
--- a/README.md
+++ b/README.md
@@ -1,97 +1,179 @@
-# centre-tokens
-
-Fiat tokens on the [CENTRE](https://centre.io) network.
+
+
+# Circle's Stablecoin Smart Contracts on EVM-compatible blockchains
+
+
+This repository contains the smart contracts used by
+[Circle's](https://www.circle.com/) stablecoins on EVM-compatible blockchains.
+All contracts are written in [Solidity](https://soliditylang.org/) and managed
+by the [Hardhat](https://hardhat.org/) framework.
+
+
+
+## Table of contents
+
+
+- [Setup](#setup)
+ - [Development Environment](#development-environment)
+ - [IDE](#ide)
+- [Development](#development)
+ - [TypeScript type definition files for the contracts](#typescript-type-definition-files-for-the-contracts)
+ - [Linting and Formatting](#linting-and-formatting)
+ - [Testing](#testing)
+- [Deployment](#deployment)
+- [Contracts](#contracts)
+- [FiatToken features](#fiattoken-features)
+ - [ERC20 compatible](#erc20-compatible)
+ - [Pausable](#pausable)
+ - [Upgradable](#upgradable)
+ - [Blacklist](#blacklist)
+ - [Minting/Burning](#mintingburning)
+ - [Ownable](#ownable)
+- [Additional Documentations](#additional-documentations)
## Setup
+### Development Environment
+
Requirements:
-- Node >= v12
-- Yarn
+- Node 20.9.0
+- Yarn 1.22.19
+- [Foundry@f625d0f](https://github.com/foundry-rs/foundry/releases/tag/nightly-f625d0fa7c51e65b4bf1e8f7931cd1c6e2e285e9)
+```sh
+$ nvm use
+$ npm i -g yarn@1.22.19 # Install yarn if you don't already have it
+$ yarn install # Install npm packages and other dependencies listed in setup.sh
```
-$ git clone git@github.com:centrehq/centre-tokens.git
-$ cd centre-tokens
-$ npm i -g yarn # Install yarn if you don't already have it
-$ yarn install # Install dependencies
-$ yarn setup # Setup Git hooks
-```
-## TypeScript type definition files for the contracts
+### IDE
+
+We recommend using VSCode for the project here with these
+[extensions](./.vscode/extensions.json) installed.
+
+## Development
-To generate type definitions:
+### TypeScript type definition files for the contracts
+Types are automatically generated as a part of contract compilation:
+
+```sh
+$ yarn compile
```
-$ yarn compile && yarn typechain
+
+To generate typing without re-compiling, run
+
+```sh
+$ yarn hardhat typechain
```
-## Linting and Formatting
+### Linting and Formatting
To check code for problems:
+```sh
+$ yarn static-check # Runs a static check on the repo.
```
+
+or run the checks individually:
+
+```sh
$ yarn typecheck # Type-check TypeScript code
$ yarn lint # Check JavaScript and TypeScript code
$ yarn lint --fix # Fix problems where possible
$ yarn solhint # Check Solidity code
-$ yarn slither # Run Slither
```
To auto-format code:
-```
+```sh
$ yarn fmt
```
-## Testing
-
-First, make sure Ganache is running.
-
-```
-$ yarn ganache
-```
+### Testing
Run all tests:
-```
+```sh
$ yarn test
```
To run tests in a specific file, run:
-```
+```sh
$ yarn test [path/to/file]
```
To run tests and generate test coverage, run:
-```
+```sh
$ yarn coverage
```
+To check the size of contracts in the repo, run the following command.
+
+```sh
+$ yarn contract-size # Ignores tests
+```
+
## Deployment
-Create a copy of the file `config.js.example`, and name it `config.js`. Enter
-the BIP39 mnemonic phrase, the INFURA API key to use for deployment, and the
-addresses of proxy admin, owner, master minter, blacklister, and pauser in
-`config.js`. This file must not be checked into the repository. To prevent
-accidental check-ins, `config.js` is in `.gitignore`.
+1. Create a copy of the file `.env.example`, and name it `.env`. Fill in
+ appropriate values in the `.env` file. This file must not be checked into the
+ repository.
+
+```sh
+cp .env.example .env
+```
+
+2. Create a `blacklist.remote.json` file and populate it with a list of
+ addresses to be blacklisted. This file must not be checked into the
+ repository.
+
+```sh
+echo "[]" > blacklist.remote.json
+```
+
+3. Simulate a deployment by running the following command
-Run `yarn migrate --network NETWORK`, where NETWORK is either `mainnet` or
-`ropsten`.
+```sh
+yarn forge:simulate scripts/deploy/deploy-fiat-token.s.sol --rpc-url
+```
+
+4. Validate that all transactions to be broadcasted are filled in with the
+ correct values
+5. Deploy the contracts by running the following command
+
+```sh
+yarn forge:broadcast scripts/deploy/deploy-fiat-token.s.sol --rpc-url
+```
+
+6. Verify the contracts on an Etherscan flavored block explorer by running the
+ following command. Ensure that `ETHERSCAN_KEY` is set in the `.env` file.
+
+```sh
+yarn forge:verify scripts/deploy/deploy-fiat-token.s.sol --rpc-url
+```
## Contracts
-The implementation uses 2 separate contracts - a proxy contract
-(`FiatTokenProxy.sol`) and an implementation contract (`FiatToken.sol`). This
-allows upgrading the contract, as a new implementation contact can be deployed
-and the Proxy updated to point to it.
+The FiatToken contracts adheres to OpenZeppelin's
+[Proxy Upgrade Pattern](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies)
+([permalink](https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/65cf285bd36af24570186ca6409341540c67238a/docs/modules/ROOT/pages/proxies.adoc#L1)).
+There are 2 main contracts - an implementation contract
+([`FiatTokenV2_2.sol`](./contracts/v2/FiatTokenV2_2.sol)) that contains the main
+logic for FiatToken's functionalities, and a proxy contract
+([`FiatTokenProxy.sol`](./contracts/v1/FiatTokenProxy.sol)) that redirects
+function calls to the implementation contract. This allows upgrading FiatToken's
+functionalities, as a new implementation contact can be deployed and the Proxy
+can be updated to point to it.
-### FiatToken
+## FiatToken features
The FiatToken offers a number of capabilities, which briefly are described
below. There are more [detailed design docs](./doc/tokendesign.md) in the `doc`
-folder.
+directory.
### ERC20 compatible
@@ -130,3 +212,13 @@ the `masterMinter`.
The contract has an Owner, who can change the `owner`, `pauser`, `blacklister`,
or `masterMinter` addresses. The `owner` can not change the `proxyOwner`
address.
+
+## Additional Documentations
+
+- [FiatToken design](./doc/tokendesign.md)
+- [MasterMinter design](./doc/masterminter.md)
+- [Bridged USDC Standard](./doc/bridged_USDC_standard.md)
+- [Deployment process](./doc/deployment.md)
+- [Preparing an upgrade](./doc/upgrade.md)
+- [Upgrading from v2.1 to v2.2](./doc/v2.2_upgrade.md)
+- [Celo FiatToken extension](./doc/celo.md)
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..b30df6a56
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,8 @@
+# Security Policy
+
+## Reporting a Vulnerability
+
+Please do not file public issues on Github for security vulnerabilities. All
+security vulnerabilities should be reported to Circle privately, through
+Circle's [Bug Bounty Program](https://hackerone.com/circle-bbp). Please read
+through the program policy before submitting a report.
diff --git a/build-dev.sh b/build-dev.sh
deleted file mode 100755
index 6a9956e10..000000000
--- a/build-dev.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-DOCROOT="$( cd "$( dirname "$0" )" && pwd )"
-
-# compile solidity contracts
-docker-compose -f $DOCROOT/docker-compose.yml run --rm truffle compile
-
-# run solidity tests
-docker-compose -f $DOCROOT/docker-compose.yml run --rm truffle --network local_testnet test
-
-#stop containers
-docker-compose -f $DOCROOT/docker-compose.yml down
diff --git a/buildspec.yaml b/buildspec.yaml
deleted file mode 100644
index f526118bb..000000000
--- a/buildspec.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-version: 0.2
-
-phases:
- install:
- commands:
- - npm install -g yarn@^1.9.2
- - npm install -g truffle@4.1.13
- - yarn install --frozen-lockfile
- #- npm install
- build:
- commands:
- - echo Build started on `date`
- - yarn check --integrity
- - mkdir -p build/logs
- - truffle compile
- - npm test
- post_build:
- commands:
- - isPR=$(echo $CODEBUILD_SOURCE_VERSION | grep -c 'pr/') || true
- - succeeded=$CODEBUILD_BUILD_SUCCEEDING
- - echo "isPR status:${isPR}"
- - echo "succeeded status:${succeeded}"
- - if [ $isPR -ne 1 ] && [ $succeeded -ne 1 ]; then echo "Build failed in main repo -- sending notification"; aws sns publish --topic-arn ${FailedBuildTopic} --message "Build Notification - centre-tokens build failed!"; else echo "Build succeeded and/or PR build -- not sending notification"; fi
-
-artifacts:
- files:
- - build/contracts/*
- - coverage/**/*
diff --git a/cached_artifacts/opMainnetFiatTokenProxyContractCreationBytecode.bin b/cached_artifacts/opMainnetFiatTokenProxyContractCreationBytecode.bin
new file mode 100644
index 000000000..65beae8be
--- /dev/null
+++ b/cached_artifacts/opMainnetFiatTokenProxyContractCreationBytecode.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b506040516108a93803806108a98339818101604052602081101561003357600080fd5b5051808061004081610051565b5061004a336100c3565b5050610123565b610064816100e760201b61042a1760201c565b61009f5760405162461bcd60e51b815260040180806020018281038252603b81526020018061086e603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061011b57508115155b949350505050565b61073c806101326000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146101315780638f2839701461016f578063f851a440146101af5761005a565b80633659cfe6146100645780634f1ef286146100a4575b6100626101c4565b005b34801561007057600080fd5b506100626004803603602081101561008757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101de565b610062600480360360408110156100ba57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156100f257600080fd5b82018360208201111561010457600080fd5b8035906020019184600183028401116401000000008311171561012657600080fd5b509092509050610232565b34801561013d57600080fd5b50610146610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561017b57600080fd5b506100626004803603602081101561019257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610318565b3480156101bb57600080fd5b50610146610420565b6101cc610466565b6101dc6101d76104fa565b61051f565b565b6101e6610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275761022281610568565b61022f565b61022f6101c4565b50565b61023a610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fc5761027683610568565b60003073ffffffffffffffffffffffffffffffffffffffff16348484604051808383808284376040519201945060009350909150508083038185875af1925050503d80600081146102e3576040519150601f19603f3d011682016040523d82523d6000602084013e6102e8565b606091505b50509050806102f657600080fd5b50610304565b6103046101c4565b505050565b60006103136104fa565b905090565b610320610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275773ffffffffffffffffffffffffffffffffffffffff81166103bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806106966036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103e8610543565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a1610222816105bd565b6000610313610543565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061045e57508115155b949350505050565b61046e610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806106646032913960400191505060405180910390fd5b6101dc6101dc565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e80801561053e573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b610571816105e1565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6105ea8161042a565b61063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806106cc603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220046bec85a39556fa01d3014f9bbd881bf3dfd8a920836836698508b80c55e88964736f6c634300060c003343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000000000000000000bd17deee53a58b48548117a11a2e7bbf2d0d6fa7
\ No newline at end of file
diff --git a/cached_artifacts/opMainnetFiatTokenProxyRuntimeBytecode.bin b/cached_artifacts/opMainnetFiatTokenProxyRuntimeBytecode.bin
new file mode 100644
index 000000000..10780a6e7
--- /dev/null
+++ b/cached_artifacts/opMainnetFiatTokenProxyRuntimeBytecode.bin
@@ -0,0 +1 @@
+60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146101315780638f2839701461016f578063f851a440146101af5761005a565b80633659cfe6146100645780634f1ef286146100a4575b6100626101c4565b005b34801561007057600080fd5b506100626004803603602081101561008757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101de565b610062600480360360408110156100ba57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156100f257600080fd5b82018360208201111561010457600080fd5b8035906020019184600183028401116401000000008311171561012657600080fd5b509092509050610232565b34801561013d57600080fd5b50610146610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561017b57600080fd5b506100626004803603602081101561019257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610318565b3480156101bb57600080fd5b50610146610420565b6101cc610466565b6101dc6101d76104fa565b61051f565b565b6101e6610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275761022281610568565b61022f565b61022f6101c4565b50565b61023a610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fc5761027683610568565b60003073ffffffffffffffffffffffffffffffffffffffff16348484604051808383808284376040519201945060009350909150508083038185875af1925050503d80600081146102e3576040519150601f19603f3d011682016040523d82523d6000602084013e6102e8565b606091505b50509050806102f657600080fd5b50610304565b6103046101c4565b505050565b60006103136104fa565b905090565b610320610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275773ffffffffffffffffffffffffffffffffffffffff81166103bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806106966036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103e8610543565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a1610222816105bd565b6000610313610543565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061045e57508115155b949350505050565b61046e610543565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806106646032913960400191505060405180910390fd5b6101dc6101dc565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e80801561053e573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b610571816105e1565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6105ea8161042a565b61063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806106cc603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220046bec85a39556fa01d3014f9bbd881bf3dfd8a920836836698508b80c55e88964736f6c634300060c0033
\ No newline at end of file
diff --git a/ci/codebuild.yaml b/ci/codebuild.yaml
deleted file mode 100644
index 43a75d77d..000000000
--- a/ci/codebuild.yaml
+++ /dev/null
@@ -1,106 +0,0 @@
-AWSTemplateFormatVersion: "2010-09-09"
-Description: CI for Centre Tokens
-Parameters:
-
- StackName:
- Default: ci-centre-tokens
- Type: String
- Description: Cloudformation stack name
-
- GithubRepoOwner:
- Default: centrehq
- Type: String
- Description: Github Owner
-
- GithubRepo:
- Default: centre-tokens
- Type: String
- Description: Github repository name
-
- GithubBranch:
- Default: master
- Type: String
- Description: Github branch
-
- ECRBuildImage:
- Default: "aws/codebuild/nodejs:8.11.0"
- Type: String
- Description: The ECR image to use in the Codebuild project
-
-Resources:
-
- # Note: Webhooks can not be enabled via Cloudformation and must be done manually
- CodeBuildProject:
- Type: "AWS::CodeBuild::Project"
- Properties:
- Name: "centre-tokens"
- Description: !Sub "Codebuild project from stack ${AWS::StackName}"
- Artifacts:
- Type: S3
- Location: !Ref CodeBuildBucket
- Name: artifacts
- NamespaceType: BUILD_ID
- BadgeEnabled: true
- Environment:
- Type: LINUX_CONTAINER
- ComputeType: BUILD_GENERAL1_SMALL
- Image: !Ref ECRBuildImage
- EnvironmentVariables:
- - Name: FailedBuildTopic
- Value: !Ref FailedBuildTopic
- ServiceRole: !Ref CodeBuildServiceRole
- Source:
- Type: GITHUB
- BuildSpec: "buildspec.yaml"
- Location: !Sub "https://github.com/${GithubRepoOwner}/${GithubRepo}.git"
- Auth:
- Type: OAUTH
- GitCloneDepth: 1
- TimeoutInMinutes: 60
-
- CodeBuildBucket:
- Type: "AWS::S3::Bucket"
- Properties:
- AccessControl: "Private"
- BucketName: !Sub "${AWS::StackName}-${AWS::AccountId}-${AWS::Region}"
- VersioningConfiguration:
- Status: Enabled
-
- CodeBuildServiceRole:
- Type: "AWS::IAM::Role"
- Properties:
- AssumeRolePolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Effect: "Allow"
- Principal:
- Service:
- - "codebuild.amazonaws.com"
- Action: "sts:AssumeRole"
- Path: "/"
- Policies:
- - PolicyName: "CodeBuildAccess"
- PolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Sid: "AllowToCreateLogs"
- Effect: "Allow"
- Action:
- - "logs:CreateLogGroup"
- - "logs:CreateLogStream"
- - "logs:PutLogEvents"
- Resource:
- - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/centre-tokens:log-stream:*"
- - Sid: "AllowPutToBucket"
- Effect: "Allow"
- Action:
- - "s3:PutObject*"
- Resource: !Sub "arn:aws:s3:::${AWS::StackName}-${AWS::AccountId}-${AWS::Region}*"
- - Sid: "AllowPublishToSNS"
- Effect: "Allow"
- Action:
- - "SNS:Publish"
- Resource: !Ref FailedBuildTopic
-
- FailedBuildTopic:
- Type: AWS::SNS::Topic
diff --git a/config.js.example b/config.js.example
deleted file mode 100644
index 726e5f38e..000000000
--- a/config.js.example
+++ /dev/null
@@ -1,18 +0,0 @@
-module.exports = {
- // BIP39 mnemonic phrase
- MNEMONIC: "",
- // INFURA API key
- INFURA_KEY: "",
- // FiatTokenProxy admin - can upgrade implementation contract
- PROXY_ADMIN_ADDRESS: "",
- // Owner - can configure master minter, pauser, and blacklister
- OWNER_ADDRESS: "",
- // Master Minter - can configure minters and minter allowance
- MASTERMINTER_ADDRESS: "",
- // Pauser - can pause the contract
- PAUSER_ADDRESS: "",
- // Blacklister - can blacklist addresses
- BLACKLISTER_ADDRESS: "",
- // FiatTokenProxy contract - override the contract address used in migrations
- PROXY_CONTRACT_ADDRESS: "",
-};
diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol
deleted file mode 100644
index 66d81765b..000000000
--- a/contracts/Migrations.sol
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * SPDX-License-Identifier: MIT
- *
- * Copyright (c) 2018-2020 CENTRE SECZ
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-pragma solidity 0.6.12;
-
-contract Migrations {
- address public owner;
- uint256 public last_completed_migration;
-
- modifier restricted() {
- if (msg.sender == owner) _;
- }
-
- constructor() public {
- owner = msg.sender;
- }
-
- function setCompleted(uint256 completed) external restricted {
- last_completed_migration = completed;
- }
-
- function upgrade(address new_address) external restricted {
- Migrations upgraded = Migrations(new_address);
- upgraded.setCompleted(last_completed_migration);
- }
-}
diff --git a/contracts/interface/IERC1271.sol b/contracts/interface/IERC1271.sol
new file mode 100644
index 000000000..b8ca9841c
--- /dev/null
+++ b/contracts/interface/IERC1271.sol
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+/**
+ * @dev Interface of the ERC1271 standard signature validation method for
+ * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
+ */
+interface IERC1271 {
+ /**
+ * @dev Should return whether the signature provided is valid for the provided data
+ * @param hash Hash of the data to be signed
+ * @param signature Signature byte array associated with the provided data hash
+ * @return magicValue bytes4 magic value 0x1626ba7e when function passes
+ */
+ function isValidSignature(bytes32 hash, bytes memory signature)
+ external
+ view
+ returns (bytes4 magicValue);
+}
diff --git a/contracts/interface/celo/ICeloGasToken.sol b/contracts/interface/celo/ICeloGasToken.sol
new file mode 100644
index 000000000..072e30358
--- /dev/null
+++ b/contracts/interface/celo/ICeloGasToken.sol
@@ -0,0 +1,68 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+
+/**
+ * @dev Interface of the Celo gas token standard for contracts
+ * as defined at https://docs.celo.org/learn/add-gas-currency.
+ */
+interface ICeloGasToken is IERC20 {
+ /**
+ * @notice Reserve balance for making payments for gas in this FiatToken currency.
+ * @param from The address from which to reserve balance.
+ * @param value The amount of balance to reserve.
+ * @dev This function is called by the Celo protocol when paying for transaction fees in this
+ * currency. After the transaction is executed, unused gas is refunded to the sender and credited
+ * to the various fee recipients via a call to `creditGasFees`. The events emitted by `creditGasFees`
+ * reflect the *net* gas fee payments for the transaction.
+ */
+ function debitGasFees(address from, uint256 value) external;
+
+ /**
+ * @notice Credit balances of original payer and various fee recipients
+ * after having made payments for gas in the form of this FiatToken currency.
+ * @param from The original payer address from which balance was reserved via `debitGasFees`.
+ * @param feeRecipient The main fee recipient address.
+ * @param gatewayFeeRecipient Gateway address.
+ * @param communityFund Celo Community Fund address.
+ * @param refund Amount to be refunded by the VM to `from`.
+ * @param tipTxFee Amount to distribute to `feeRecipient`.
+ * @param gatewayFee Amount to distribute to `gatewayFeeRecipient`; this is deprecated and will always be 0.
+ * @param baseTxFee Amount to distribute to `communityFund`.
+ * @dev This function is called by the Celo protocol when paying for transaction fees in this
+ * currency. After the transaction is executed, unused gas is refunded to the sender and credited
+ * to the various fee recipients via a call to `creditGasFees`. The events emitted by `creditGasFees`
+ * reflect the *net* gas fee payments for the transaction. As an invariant, the original debited amount
+ * will always equal (refund + tipTxFee + gatewayFee + baseTxFee). Though the amount debited in debitGasFees
+ * is always equal to (refund + tipTxFee + gatewayFee + baseTxFee), in practice, the gateway fee is never
+ * used (0) and should ideally be ignored except in the function signature to optimize gas savings.
+ */
+ function creditGasFees(
+ address from,
+ address feeRecipient,
+ address gatewayFeeRecipient,
+ address communityFund,
+ uint256 refund,
+ uint256 tipTxFee,
+ uint256 gatewayFee,
+ uint256 baseTxFee
+ ) external;
+}
diff --git a/contracts/interface/celo/IDecimals.sol b/contracts/interface/celo/IDecimals.sol
new file mode 100644
index 000000000..a1f031894
--- /dev/null
+++ b/contracts/interface/celo/IDecimals.sol
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+/**
+ * @dev Interface for a contract, namely a currency token, that
+ * exposes how many decimals it has. While IERC20 does not define
+ * a `decimals` field, in practice, almost all standard ERC20s do
+ * themselves have a `decimals` field.
+ */
+interface IDecimals {
+ function decimals() external view returns (uint8);
+}
diff --git a/contracts/interface/celo/IFiatTokenFeeAdapter.sol b/contracts/interface/celo/IFiatTokenFeeAdapter.sol
new file mode 100644
index 000000000..77676c1bb
--- /dev/null
+++ b/contracts/interface/celo/IFiatTokenFeeAdapter.sol
@@ -0,0 +1,79 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+/**
+ * @dev Barebones interface of the fee currency adapter standard for
+ * ERC-20 gas tokens that do not operate with 18 decimals. At a mini-
+ * mum, an implementation must support balance queries, debiting, and
+ * crediting to work with the Celo VM.
+ */
+interface IFiatTokenFeeAdapter {
+ /**
+ * @notice Return the balance of the address specified, but this balance
+ * is scaled appropriately to the number of decimals on this adapter.
+ * @dev The Celo VM calls balanceOf during its fee calculations on custom
+ * currencies to ensure that the holder has enough; since the VM debits
+ * and credits upscaled values, it needs to reference upscaled balances
+ * as well. See
+ * https://github.com/celo-org/celo-blockchain/blob/3808c45addf56cf547581599a1cb059bc4ae5089/core/state_transition.go#L321.
+ */
+ function balanceOf(address account) external view returns (uint256);
+
+ /**
+ * @notice Reserve *adapted* balance for making payments for gas in this FiatToken currency.
+ * @param from The address from which to reserve balance.
+ * @param value The amount of balance to reserve.
+ * @dev This function is called by the Celo protocol when paying for transaction fees in this
+ * currency. After the transaction is executed, unused gas is refunded to the sender and credited
+ * to the various fee recipients via a call to `creditGasFees`. The events emitted by `creditGasFees`
+ * reflect the *net* gas fee payments for the transaction.
+ */
+ function debitGasFees(address from, uint256 value) external;
+
+ /**
+ * @notice Credit *adapted* balances of original payer and various fee recipients
+ * after having made payments for gas in the form of this FiatToken currency.
+ * @param from The original payer address from which balance was reserved via `debitGasFees`.
+ * @param feeRecipient The main fee recipient address.
+ * @param gatewayFeeRecipient Gateway address.
+ * @param communityFund Celo Community Fund address.
+ * @param refund Amount to be refunded by the VM to `from`.
+ * @param tipTxFee Amount to distribute to `feeRecipient`.
+ * @param gatewayFee Amount to distribute to `gatewayFeeRecipient`; this is deprecated and will always be 0.
+ * @param baseTxFee Amount to distribute to `communityFund`.
+ * @dev This function is called by the Celo protocol when paying for transaction fees in this
+ * currency. After the transaction is executed, unused gas is refunded to the sender and credited
+ * to the various fee recipients via a call to `creditGasFees`. The events emitted by `creditGasFees`
+ * reflect the *net* gas fee payments for the transaction. As an invariant, the original debited amount
+ * will always equal (refund + tipTxFee + gatewayFee + baseTxFee). Though the amount debited in debitGasFees
+ * is always equal to (refund + tipTxFee + gatewayFee + baseTxFee), in practice, the gateway fee is never
+ * used (0) and should ideally be ignored except in the function signature to optimize gas savings.
+ */
+ function creditGasFees(
+ address from,
+ address feeRecipient,
+ address gatewayFeeRecipient,
+ address communityFund,
+ uint256 refund,
+ uint256 tipTxFee,
+ uint256 gatewayFee,
+ uint256 baseTxFee
+ ) external;
+}
diff --git a/contracts/minting/Controller.sol b/contracts/minting/Controller.sol
new file mode 100644
index 000000000..12c36f3c1
--- /dev/null
+++ b/contracts/minting/Controller.sol
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { Ownable } from "../v1/Ownable.sol";
+
+/**
+ * @title Controller
+ * @notice Generic implementation of the owner-controller-worker model.
+ * One owner manages many controllers. Each controller manages one worker.
+ * Workers may be reused across different controllers.
+ */
+contract Controller is Ownable {
+ /**
+ * @dev A controller manages a single worker address.
+ * controllers[controller] = worker
+ */
+ mapping(address => address) internal controllers;
+
+ event ControllerConfigured(
+ address indexed _controller,
+ address indexed _worker
+ );
+ event ControllerRemoved(address indexed _controller);
+
+ /**
+ * @notice Ensures that caller is the controller of a non-zero worker
+ * address.
+ */
+ modifier onlyController() {
+ require(
+ controllers[msg.sender] != address(0),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ _;
+ }
+
+ /**
+ * @notice Gets the worker at address _controller.
+ */
+ function getWorker(address _controller) external view returns (address) {
+ return controllers[_controller];
+ }
+
+ // onlyOwner functions
+
+ /**
+ * @notice Configure a controller with the given worker.
+ * @param _controller The controller to be configured with a worker.
+ * @param _worker The worker to be set for the newly configured controller.
+ * _worker must not be a non-zero address. To disable a worker,
+ * use removeController instead.
+ */
+ function configureController(address _controller, address _worker)
+ public
+ onlyOwner
+ {
+ require(
+ _controller != address(0),
+ "Controller must be a non-zero address"
+ );
+ require(_worker != address(0), "Worker must be a non-zero address");
+ controllers[_controller] = _worker;
+ emit ControllerConfigured(_controller, _worker);
+ }
+
+ /**
+ * @notice disables a controller by setting its worker to address(0).
+ * @param _controller The controller to disable.
+ */
+ function removeController(address _controller) public onlyOwner {
+ require(
+ _controller != address(0),
+ "Controller must be a non-zero address"
+ );
+ require(
+ controllers[_controller] != address(0),
+ "Worker must be a non-zero address"
+ );
+ controllers[_controller] = address(0);
+ emit ControllerRemoved(_controller);
+ }
+}
diff --git a/contracts/minting/MasterMinter.sol b/contracts/minting/MasterMinter.sol
new file mode 100644
index 000000000..f75064107
--- /dev/null
+++ b/contracts/minting/MasterMinter.sol
@@ -0,0 +1,31 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { MintController } from "./MintController.sol";
+
+/**
+ * @title MasterMinter
+ * @notice MasterMinter uses multiple controllers to manage minters for a
+ * contract that implements the MinterManagerInterface.
+ * @dev MasterMinter inherits all its functionality from MintController.
+ */
+contract MasterMinter is MintController {
+ constructor(address _minterManager) public MintController(_minterManager) {}
+}
diff --git a/contracts/minting/MintController.sol b/contracts/minting/MintController.sol
new file mode 100644
index 000000000..2f2c6b5c6
--- /dev/null
+++ b/contracts/minting/MintController.sol
@@ -0,0 +1,213 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { Controller } from "./Controller.sol";
+import { MinterManagementInterface } from "./MinterManagementInterface.sol";
+import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
+
+// solhint-disable func-name-mixedcase
+
+/**
+ * @title MintController
+ * @dev The MintController contract manages minters for a contract that
+ * implements the MinterManagerInterface. It lets the owner designate certain
+ * addresses as controllers, and these controllers then manage the
+ * minters by adding and removing minters, as well as modifying their minting
+ * allowance. A controller may manage exactly one minter, but the same minter
+ * address may be managed by multiple controllers.
+ * MintController inherits from the Controller contract. It treats the
+ * Controller workers as minters.
+ */
+contract MintController is Controller {
+ using SafeMath for uint256;
+
+ /**
+ * @dev MintController calls the minterManager to execute/record minter
+ * management tasks, as well as to query the status of a minter address.
+ */
+ MinterManagementInterface internal minterManager;
+
+ event MinterManagerSet(
+ address indexed _oldMinterManager,
+ address indexed _newMinterManager
+ );
+ event MinterConfigured(
+ address indexed _msgSender,
+ address indexed _minter,
+ uint256 _allowance
+ );
+ event MinterRemoved(address indexed _msgSender, address indexed _minter);
+ event MinterAllowanceIncremented(
+ address indexed _msgSender,
+ address indexed _minter,
+ uint256 _increment,
+ uint256 _newAllowance
+ );
+
+ event MinterAllowanceDecremented(
+ address indexed msgSender,
+ address indexed minter,
+ uint256 decrement,
+ uint256 newAllowance
+ );
+
+ /**
+ * @notice Initializes the minterManager.
+ * @param _minterManager The address of the minterManager contract.
+ */
+ constructor(address _minterManager) public {
+ minterManager = MinterManagementInterface(_minterManager);
+ }
+
+ /**
+ * @notice gets the minterManager
+ */
+ function getMinterManager()
+ external
+ view
+ returns (MinterManagementInterface)
+ {
+ return minterManager;
+ }
+
+ // onlyOwner functions
+
+ /**
+ * @notice Sets the minterManager.
+ * @param _newMinterManager The address of the new minterManager contract.
+ */
+ function setMinterManager(address _newMinterManager) public onlyOwner {
+ emit MinterManagerSet(address(minterManager), _newMinterManager);
+ minterManager = MinterManagementInterface(_newMinterManager);
+ }
+
+ // onlyController functions
+
+ /**
+ * @notice Removes the controller's own minter.
+ */
+ function removeMinter() public onlyController returns (bool) {
+ address minter = controllers[msg.sender];
+ emit MinterRemoved(msg.sender, minter);
+ return minterManager.removeMinter(minter);
+ }
+
+ /**
+ * @notice Enables the minter and sets its allowance.
+ * @param _newAllowance New allowance to be set for minter.
+ */
+ function configureMinter(uint256 _newAllowance)
+ public
+ onlyController
+ returns (bool)
+ {
+ address minter = controllers[msg.sender];
+ emit MinterConfigured(msg.sender, minter, _newAllowance);
+ return internal_setMinterAllowance(minter, _newAllowance);
+ }
+
+ /**
+ * @notice Increases the minter's allowance if and only if the minter is an
+ * active minter.
+ * @dev An minter is considered active if minterManager.isMinter(minter)
+ * returns true.
+ */
+ function incrementMinterAllowance(uint256 _allowanceIncrement)
+ public
+ onlyController
+ returns (bool)
+ {
+ require(
+ _allowanceIncrement > 0,
+ "Allowance increment must be greater than 0"
+ );
+ address minter = controllers[msg.sender];
+ require(
+ minterManager.isMinter(minter),
+ "Can only increment allowance for minters in minterManager"
+ );
+
+ uint256 currentAllowance = minterManager.minterAllowance(minter);
+ uint256 newAllowance = currentAllowance.add(_allowanceIncrement);
+
+ emit MinterAllowanceIncremented(
+ msg.sender,
+ minter,
+ _allowanceIncrement,
+ newAllowance
+ );
+
+ return internal_setMinterAllowance(minter, newAllowance);
+ }
+
+ /**
+ * @notice decreases the minter allowance if and only if the minter is
+ * currently active. The controller can safely send a signed
+ * decrementMinterAllowance() transaction to a minter and not worry
+ * about it being used to undo a removeMinter() transaction.
+ */
+ function decrementMinterAllowance(uint256 _allowanceDecrement)
+ public
+ onlyController
+ returns (bool)
+ {
+ require(
+ _allowanceDecrement > 0,
+ "Allowance decrement must be greater than 0"
+ );
+ address minter = controllers[msg.sender];
+ require(
+ minterManager.isMinter(minter),
+ "Can only decrement allowance for minters in minterManager"
+ );
+
+ uint256 currentAllowance = minterManager.minterAllowance(minter);
+ uint256 actualAllowanceDecrement = (
+ currentAllowance > _allowanceDecrement
+ ? _allowanceDecrement
+ : currentAllowance
+ );
+ uint256 newAllowance = currentAllowance.sub(actualAllowanceDecrement);
+
+ emit MinterAllowanceDecremented(
+ msg.sender,
+ minter,
+ actualAllowanceDecrement,
+ newAllowance
+ );
+
+ return internal_setMinterAllowance(minter, newAllowance);
+ }
+
+ // Internal functions
+
+ /**
+ * @notice Uses the MinterManagementInterface to enable the minter and
+ * set its allowance.
+ * @param _minter Minter to set new allowance of.
+ * @param _newAllowance New allowance to be set for minter.
+ */
+ function internal_setMinterAllowance(address _minter, uint256 _newAllowance)
+ internal
+ returns (bool)
+ {
+ return minterManager.configureMinter(_minter, _newAllowance);
+ }
+}
diff --git a/contracts/minting/MinterManagementInterface.sol b/contracts/minting/MinterManagementInterface.sol
new file mode 100644
index 000000000..1b8eddfbd
--- /dev/null
+++ b/contracts/minting/MinterManagementInterface.sol
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+/**
+ * @dev A contract that implements the MinterManagementInterface has external
+ * functions for adding and removing minters and modifying their allowances.
+ * An example is the FiatTokenV1 contract.
+ */
+interface MinterManagementInterface {
+ function isMinter(address _account) external view returns (bool);
+
+ function minterAllowance(address _minter) external view returns (uint256);
+
+ function configureMinter(address _minter, uint256 _minterAllowedAmount)
+ external
+ returns (bool);
+
+ function removeMinter(address _minter) external returns (bool);
+}
diff --git a/contracts/test/ContractThatCallsPublicFunctions.sol b/contracts/test/ContractThatCallsPublicFunctions.sol
index 6602ffec3..7ded0cd9a 100644
--- a/contracts/test/ContractThatCallsPublicFunctions.sol
+++ b/contracts/test/ContractThatCallsPublicFunctions.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/test/ContractThatReverts.sol b/contracts/test/ContractThatReverts.sol
index 722709da1..bed257b09 100644
--- a/contracts/test/ContractThatReverts.sol
+++ b/contracts/test/ContractThatReverts.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/test/ContractWithExternalFunctions.sol b/contracts/test/ContractWithExternalFunctions.sol
index 10eb59286..8c5f64ade 100644
--- a/contracts/test/ContractWithExternalFunctions.sol
+++ b/contracts/test/ContractWithExternalFunctions.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/test/ContractWithPublicFunctions.sol b/contracts/test/ContractWithPublicFunctions.sol
index 4c2f8f4df..f4e29e2e4 100644
--- a/contracts/test/ContractWithPublicFunctions.sol
+++ b/contracts/test/ContractWithPublicFunctions.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/test/DummyERC20.sol b/contracts/test/DummyERC20.sol
index d1ae4f014..306ecc30e 100644
--- a/contracts/test/DummyERC20.sol
+++ b/contracts/test/DummyERC20.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/test/ECRecoverTest.sol b/contracts/test/ECRecoverTest.sol
index 7518fb65d..d3f81c15b 100644
--- a/contracts/test/ECRecoverTest.sol
+++ b/contracts/test/ECRecoverTest.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
@@ -27,12 +21,11 @@ pragma solidity 0.6.12;
import { ECRecover } from "../util/ECRecover.sol";
contract ECRecoverTest {
- function recover(
- bytes32 digest,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) external pure returns (address) {
- return ECRecover.recover(digest, v, r, s);
+ function recover(bytes32 digest, bytes memory signature)
+ external
+ pure
+ returns (address)
+ {
+ return ECRecover.recover(digest, signature);
}
}
diff --git a/contracts/test/EIP712Test.sol b/contracts/test/EIP712Test.sol
index fe54065f5..cd80cb828 100644
--- a/contracts/test/EIP712Test.sol
+++ b/contracts/test/EIP712Test.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
@@ -34,14 +28,4 @@ contract EIP712Test {
{
return EIP712.makeDomainSeparator(name, version);
}
-
- function recover(
- bytes32 domainSeparator,
- uint8 v,
- bytes32 r,
- bytes32 s,
- bytes calldata typeHashAndData
- ) external pure returns (address) {
- return EIP712.recover(domainSeparator, v, r, s, typeHashAndData);
- }
}
diff --git a/contracts/test/MessageHashUtilsTest.sol b/contracts/test/MessageHashUtilsTest.sol
new file mode 100644
index 000000000..890a9f294
--- /dev/null
+++ b/contracts/test/MessageHashUtilsTest.sol
@@ -0,0 +1,31 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { MessageHashUtils } from "../util/MessageHashUtils.sol";
+
+contract MessageHashUtilsTest {
+ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash)
+ external
+ pure
+ returns (bytes32 digest)
+ {
+ return MessageHashUtils.toTypedDataHash(domainSeparator, structHash);
+ }
+}
diff --git a/contracts/test/MockERC1271Wallet.sol b/contracts/test/MockERC1271Wallet.sol
new file mode 100644
index 000000000..b22497548
--- /dev/null
+++ b/contracts/test/MockERC1271Wallet.sol
@@ -0,0 +1,114 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pragma solidity 0.6.12;
+
+import { ECRecover } from "../util/ECRecover.sol";
+import { IERC1271 } from "../interface/IERC1271.sol";
+
+/**
+ * @title MockERC1271Wallet
+ * @dev An ERC-1271 compatible wallet using standard ECDSA validation.
+ */
+contract MockERC1271Wallet is IERC1271 {
+ address private _owner;
+
+ constructor(address owner) public {
+ _owner = owner;
+ }
+
+ function isValidSignature(bytes32 hash, bytes memory signature)
+ external
+ override
+ view
+ returns (bytes4 magicValue)
+ {
+ address recovered = ECRecover.recover(hash, signature);
+ return
+ recovered == _owner
+ ? IERC1271.isValidSignature.selector
+ : bytes4(0);
+ }
+}
+
+/**
+ * @title MockERC1271WalletReturningBytes32
+ * @dev Used to check against unexpected reverts from abi.decode when raw bytes data overflow the target type.
+ * Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/874c2d3c02ec1bce6af9a30bc828d3fe2079136b/contracts/mocks/ERC1271WalletMock.sol
+ */
+contract MockERC1271WalletReturningBytes32 is IERC1271 {
+ function isValidSignature(bytes32, bytes memory)
+ external
+ override
+ view
+ returns (bytes4)
+ {
+ assembly {
+ mstore(
+ 0,
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ )
+ return(0, 32)
+ }
+ }
+}
+
+/**
+ * @title MockERC1271WalletCustomValidation
+ * @dev An ERC-1271 compatible wallet that performs custom signature validation
+ */
+contract MockERC1271WalletWithCustomValidation is IERC1271 {
+ address private _owner;
+ bool private _signatureValid;
+
+ constructor(address owner) public {
+ _owner = owner;
+ }
+
+ function setSignatureValid(bool signatureValid) external {
+ _signatureValid = signatureValid;
+ }
+
+ function isValidSignature(bytes32, bytes memory)
+ external
+ override
+ view
+ returns (bytes4 magicValue)
+ {
+ return _signatureValid ? IERC1271.isValidSignature.selector : bytes4(0);
+ }
+}
+
+/**
+ * @title MockStateModifyingERC1271Wallet
+ * @dev An ERC-1271 compatible wallet that attempts to modify contract state.
+ */
+contract MockStateModifyingERC1271Wallet {
+ bool private _evoked;
+
+ function evoked() external view returns (bool) {
+ return _evoked;
+ }
+
+ function isValidSignature(bytes32, bytes memory)
+ external
+ returns (bytes4 magicValue)
+ {
+ _evoked = true;
+ return IERC1271.isValidSignature.selector;
+ }
+}
diff --git a/contracts/test/MockFiatTokenWithEditableBalanceAndBlacklistStates.sol b/contracts/test/MockFiatTokenWithEditableBalanceAndBlacklistStates.sol
new file mode 100644
index 000000000..9d7f9d30b
--- /dev/null
+++ b/contracts/test/MockFiatTokenWithEditableBalanceAndBlacklistStates.sol
@@ -0,0 +1,88 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenV2_2 } from "../v2/FiatTokenV2_2.sol";
+
+// solhint-disable func-name-mixedcase
+
+/**
+ * @title MockFiatTokenWithEditableBalanceAndBlacklistStates
+ * @dev A mock class that allows the internal balanceAndBlacklistStates to be manipulated in tests.
+ */
+contract MockFiatTokenWithEditableBalanceAndBlacklistStates is FiatTokenV2_2 {
+ /**
+ * @dev Allows the balanceAndBlacklistStates to be manipulated. This
+ * enables us to properly test the ERC20 functionalities.
+ */
+ function setBalanceAndBlacklistStates(address _account, uint256 _state)
+ external
+ {
+ balanceAndBlacklistStates[_account] = _state;
+ }
+
+ /**
+ * @dev Allows the balanceAndBlacklistStates to be read as plain values.
+ */
+ function getBalanceAndBlacklistStates(address _account)
+ external
+ view
+ returns (uint256)
+ {
+ return balanceAndBlacklistStates[_account];
+ }
+
+ /**
+ * @dev Exposes the internal function for unit testing.
+ */
+ function internal_setBlacklistState(address _account, bool _shouldBlacklist)
+ external
+ {
+ _setBlacklistState(_account, _shouldBlacklist);
+ }
+
+ /**
+ * @dev Exposes the internal function for unit testing.
+ */
+ function internal_setBalance(address _account, uint256 _balance) external {
+ _setBalance(_account, _balance);
+ }
+
+ /**
+ * @dev Exposes the internal function for unit testing.
+ */
+ function internal_isBlacklisted(address _account)
+ external
+ view
+ returns (bool)
+ {
+ return _isBlacklisted(_account);
+ }
+
+ /**
+ * @dev Exposes the internal function for unit testing.
+ */
+ function internal_balanceOf(address _account)
+ external
+ view
+ returns (uint256)
+ {
+ return _balanceOf(_account);
+ }
+}
diff --git a/contracts/test/MockFiatTokenWithEditableChainId.sol b/contracts/test/MockFiatTokenWithEditableChainId.sol
new file mode 100644
index 000000000..05e9b2e1b
--- /dev/null
+++ b/contracts/test/MockFiatTokenWithEditableChainId.sol
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenV2_2 } from "../v2/FiatTokenV2_2.sol";
+
+/**
+ * @title MockFiatTokenWithEditableChainId
+ * @dev A mock class to simulate chain ID change as a result of blockchain forks
+ */
+contract MockFiatTokenWithEditableChainId is FiatTokenV2_2 {
+ uint256 private _internalChainId = 1;
+
+ /**
+ * @dev Allow chain ID to be set to any arbitrary values.
+ */
+ function setChainId(uint256 newChainId) external {
+ _internalChainId = newChainId;
+ }
+
+ /**
+ * @return uint256 the interal chain ID previous set with user input
+ */
+ function _chainId() internal override view returns (uint256) {
+ return _internalChainId;
+ }
+
+ /**
+ * @dev Helper to allow reading current chain ID from test cases.
+ * @return uint256 the interal chain ID previous set with user input
+ */
+ function chainId() external view returns (uint256) {
+ return _chainId();
+ }
+}
diff --git a/contracts/test/UpgradedFiatToken.sol b/contracts/test/UpgradedFiatToken.sol
deleted file mode 100644
index 8f6418659..000000000
--- a/contracts/test/UpgradedFiatToken.sol
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * SPDX-License-Identifier: MIT
- *
- * Copyright (c) 2018 zOS Global Limited.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-pragma solidity 0.6.12;
-
-import { FiatTokenV1 } from "../v1/FiatTokenV1.sol";
-
-/**
- * @title UpgradedFiatToken
- * @dev ERC20 Token backed by fiat reserves
- */
-contract UpgradedFiatToken is FiatTokenV1 {
-
-}
diff --git a/contracts/test/UpgradedFiatTokenNewFieldsNewLogicTest.sol b/contracts/test/UpgradedFiatTokenNewFieldsNewLogicTest.sol
index bdfc8465f..f773d3e5c 100644
--- a/contracts/test/UpgradedFiatTokenNewFieldsNewLogicTest.sol
+++ b/contracts/test/UpgradedFiatTokenNewFieldsNewLogicTest.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/test/UpgradedFiatTokenNewFieldsTest.sol b/contracts/test/UpgradedFiatTokenNewFieldsTest.sol
index 02f01a18f..8613373b2 100644
--- a/contracts/test/UpgradedFiatTokenNewFieldsTest.sol
+++ b/contracts/test/UpgradedFiatTokenNewFieldsTest.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/test/UpgradedFiatTokenV2_2NewFieldsTest.sol b/contracts/test/UpgradedFiatTokenV2_2NewFieldsTest.sol
new file mode 100644
index 000000000..ddb46c71f
--- /dev/null
+++ b/contracts/test/UpgradedFiatTokenV2_2NewFieldsTest.sol
@@ -0,0 +1,70 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenV2_2 } from "../v2/FiatTokenV2_2.sol";
+
+/**
+ * @title UpgradedFiatTokenV2_2NewFieldsTest
+ * @dev ERC20 Token backed by fiat reserves
+ */
+contract UpgradedFiatTokenV2_2NewFieldsTest is FiatTokenV2_2 {
+ bool public newBool;
+ address public newAddress;
+ uint256 public newUint;
+ bool internal initializedV2;
+
+ function initialize(
+ string calldata tokenName,
+ string calldata tokenSymbol,
+ string calldata tokenCurrency,
+ uint8 tokenDecimals,
+ address newMasterMinter,
+ address newPauser,
+ address newBlacklister,
+ address newOwner,
+ bool _newBool,
+ address _newAddress,
+ uint256 _newUint
+ ) external {
+ super.initialize(
+ tokenName,
+ tokenSymbol,
+ tokenCurrency,
+ tokenDecimals,
+ newMasterMinter,
+ newPauser,
+ newBlacklister,
+ newOwner
+ );
+ initV2(_newBool, _newAddress, _newUint);
+ }
+
+ function initV2(
+ bool _newBool,
+ address _newAddress,
+ uint256 _newUint
+ ) public {
+ require(!initializedV2, "contract is already initialized");
+ newBool = _newBool;
+ newAddress = _newAddress;
+ newUint = _newUint;
+ initializedV2 = true;
+ }
+}
diff --git a/contracts/test/celo/MockFiatTokenCeloWithExposedFunctions.sol b/contracts/test/celo/MockFiatTokenCeloWithExposedFunctions.sol
new file mode 100644
index 000000000..ba0e7dcce
--- /dev/null
+++ b/contracts/test/celo/MockFiatTokenCeloWithExposedFunctions.sol
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenCeloV2_2 } from "../../v2/celo/FiatTokenCeloV2_2.sol";
+
+// solhint-disable func-name-mixedcase
+
+/**
+ * @dev This contract is the same as FiatTokenCeloV2_2, except, for testing,
+ * it allows us to call internal sensitive functions for testing. These
+ * external test functions are prefixed with "internal_" to differentiate
+ * them from the main internal functions.
+ */
+contract MockFiatTokenCeloWithExposedFunctions is FiatTokenCeloV2_2 {
+ function internal_debitedValue() external view returns (uint256) {
+ return _debitedValue();
+ }
+
+ function internal_transferReservedGas(
+ address from,
+ address to,
+ uint256 value
+ ) external onlyFeeCaller {
+ _transferReservedGas(from, to, value);
+ }
+
+ function internal_setBalance(address account, uint256 balance) external {
+ _setBalance(account, balance);
+ }
+}
diff --git a/contracts/test/celo/MockFiatTokenFeeAdapterWithExposedFunctions.sol b/contracts/test/celo/MockFiatTokenFeeAdapterWithExposedFunctions.sol
new file mode 100644
index 000000000..c3c09b99a
--- /dev/null
+++ b/contracts/test/celo/MockFiatTokenFeeAdapterWithExposedFunctions.sol
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenFeeAdapterV1 } from "../../v2/celo/FiatTokenFeeAdapterV1.sol";
+
+// solhint-disable func-name-mixedcase
+
+/**
+ * @dev This contract is the same as FiatTokenFeeAdapterV1, except, for testing,
+ * it allows us to call the internal upscaling and downscaling functions and
+ * allows us to override the call originator on debiting and crediting, as Web3JS
+ * and Ganache do not allow us to impersonate 0x0 (vm.prank) for tests.
+ */
+contract MockFiatTokenFeeAdapterWithExposedFunctions is FiatTokenFeeAdapterV1 {
+ address private _vmCallerAddress;
+
+ modifier onlyCeloVm() override {
+ require(
+ msg.sender == _vmCallerAddress,
+ "FiatTokenFeeAdapterV1: caller is not VM"
+ );
+ _;
+ }
+
+ function setVmCallerAddress(address newVmCallerAddress) external {
+ _vmCallerAddress = newVmCallerAddress;
+ }
+
+ function internal_debitedValue() external view returns (uint256) {
+ return _debitedValue;
+ }
+
+ function internal_upscale(uint256 value) external view returns (uint256) {
+ return _upscale(value);
+ }
+
+ function internal_downscale(uint256 value) external view returns (uint256) {
+ return _downscale(value);
+ }
+}
diff --git a/contracts/upgradeability/AdminUpgradeabilityProxy.sol b/contracts/upgradeability/AdminUpgradeabilityProxy.sol
index 5079207f3..2c9ec3cfb 100644
--- a/contracts/upgradeability/AdminUpgradeabilityProxy.sol
+++ b/contracts/upgradeability/AdminUpgradeabilityProxy.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/upgradeability/Proxy.sol b/contracts/upgradeability/Proxy.sol
index 58be93fdc..8cdd88ae8 100644
--- a/contracts/upgradeability/Proxy.sol
+++ b/contracts/upgradeability/Proxy.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/upgradeability/UpgradeabilityProxy.sol b/contracts/upgradeability/UpgradeabilityProxy.sol
index ac7562a8e..1708509f9 100644
--- a/contracts/upgradeability/UpgradeabilityProxy.sol
+++ b/contracts/upgradeability/UpgradeabilityProxy.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018 zOS Global Limited.
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/util/ECRecover.sol b/contracts/util/ECRecover.sol
index b84242ee7..ace41c1c1 100644
--- a/contracts/util/ECRecover.sol
+++ b/contracts/util/ECRecover.sol
@@ -1,26 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2016-2019 zOS Global Limited
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
@@ -72,4 +65,33 @@ library ECRecover {
return signer;
}
+
+ /**
+ * @notice Recover signer's address from a signed message
+ * @dev Adapted from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/0053ee040a7ff1dbc39691c9e67a69f564930a88/contracts/utils/cryptography/ECDSA.sol
+ * @param digest Keccak-256 hash digest of the signed message
+ * @param signature Signature byte array associated with hash
+ * @return Signer address
+ */
+ function recover(bytes32 digest, bytes memory signature)
+ internal
+ pure
+ returns (address)
+ {
+ require(signature.length == 65, "ECRecover: invalid signature length");
+
+ bytes32 r;
+ bytes32 s;
+ uint8 v;
+
+ // ecrecover takes the signature parameters, and the only way to get them
+ // currently is to use assembly.
+ /// @solidity memory-safe-assembly
+ assembly {
+ r := mload(add(signature, 0x20))
+ s := mload(add(signature, 0x40))
+ v := byte(0, mload(add(signature, 0x60)))
+ }
+ return recover(digest, v, r, s);
+ }
}
diff --git a/contracts/util/EIP712.sol b/contracts/util/EIP712.sol
index 282238e68..538a715ef 100644
--- a/contracts/util/EIP712.sol
+++ b/contracts/util/EIP712.sol
@@ -1,31 +1,23 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
-import { ECRecover } from "./ECRecover.sol";
-
/**
* @title EIP712
* @notice A library that provides EIP712 helper functions
@@ -35,22 +27,19 @@ library EIP712 {
* @notice Make EIP712 domain separator
* @param name Contract name
* @param version Contract version
+ * @param chainId Blockchain ID
* @return Domain separator
*/
- function makeDomainSeparator(string memory name, string memory version)
- internal
- view
- returns (bytes32)
- {
- uint256 chainId;
- assembly {
- chainId := chainid()
- }
+ function makeDomainSeparator(
+ string memory name,
+ string memory version,
+ uint256 chainId
+ ) internal view returns (bytes32) {
return
keccak256(
abi.encode(
+ // keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,
- // = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
keccak256(bytes(name)),
keccak256(bytes(version)),
chainId,
@@ -60,28 +49,20 @@ library EIP712 {
}
/**
- * @notice Recover signer's address from a EIP712 signature
- * @param domainSeparator Domain separator
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- * @param typeHashAndData Type hash concatenated with data
- * @return Signer's address
+ * @notice Make EIP712 domain separator
+ * @param name Contract name
+ * @param version Contract version
+ * @return Domain separator
*/
- function recover(
- bytes32 domainSeparator,
- uint8 v,
- bytes32 r,
- bytes32 s,
- bytes memory typeHashAndData
- ) internal pure returns (address) {
- bytes32 digest = keccak256(
- abi.encodePacked(
- "\x19\x01",
- domainSeparator,
- keccak256(typeHashAndData)
- )
- );
- return ECRecover.recover(digest, v, r, s);
+ function makeDomainSeparator(string memory name, string memory version)
+ internal
+ view
+ returns (bytes32)
+ {
+ uint256 chainId;
+ assembly {
+ chainId := chainid()
+ }
+ return makeDomainSeparator(name, version, chainId);
}
}
diff --git a/contracts/util/MessageHashUtils.sol b/contracts/util/MessageHashUtils.sol
new file mode 100644
index 000000000..afbfc18db
--- /dev/null
+++ b/contracts/util/MessageHashUtils.sol
@@ -0,0 +1,54 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+/**
+ * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.
+ *
+ * The library provides methods for generating a hash of a message that conforms to the
+ * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
+ * specifications.
+ */
+library MessageHashUtils {
+ /**
+ * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).
+ * Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/21bb89ef5bfc789b9333eb05e3ba2b7b284ac77c/contracts/utils/cryptography/MessageHashUtils.sol
+ *
+ * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with
+ * `\x19\x01` and hashing the result. It corresponds to the hash signed by the
+ * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.
+ *
+ * @param domainSeparator Domain separator
+ * @param structHash Hashed EIP-712 data struct
+ * @return digest The keccak256 digest of an EIP-712 typed data
+ */
+ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash)
+ internal
+ pure
+ returns (bytes32 digest)
+ {
+ assembly {
+ let ptr := mload(0x40)
+ mstore(ptr, "\x19\x01")
+ mstore(add(ptr, 0x02), domainSeparator)
+ mstore(add(ptr, 0x22), structHash)
+ digest := keccak256(ptr, 0x42)
+ }
+ }
+}
diff --git a/contracts/util/SignatureChecker.sol b/contracts/util/SignatureChecker.sol
new file mode 100644
index 000000000..7ed1a2188
--- /dev/null
+++ b/contracts/util/SignatureChecker.sol
@@ -0,0 +1,87 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { ECRecover } from "./ECRecover.sol";
+import { IERC1271 } from "../interface/IERC1271.sol";
+
+/**
+ * @dev Signature verification helper that can be used instead of `ECRecover.recover` to seamlessly support both ECDSA
+ * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets.
+ *
+ * Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/21bb89ef5bfc789b9333eb05e3ba2b7b284ac77c/contracts/utils/cryptography/SignatureChecker.sol
+ */
+library SignatureChecker {
+ /**
+ * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the
+ * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECRecover.recover`.
+ * @param signer Address of the claimed signer
+ * @param digest Keccak-256 hash digest of the signed message
+ * @param signature Signature byte array associated with hash
+ */
+ function isValidSignatureNow(
+ address signer,
+ bytes32 digest,
+ bytes memory signature
+ ) external view returns (bool) {
+ if (!isContract(signer)) {
+ return ECRecover.recover(digest, signature) == signer;
+ }
+ return isValidERC1271SignatureNow(signer, digest, signature);
+ }
+
+ /**
+ * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated
+ * against the signer smart contract using ERC1271.
+ * @param signer Address of the claimed signer
+ * @param digest Keccak-256 hash digest of the signed message
+ * @param signature Signature byte array associated with hash
+ *
+ * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
+ * change through time. It could return true at block N and false at block N+1 (or the opposite).
+ */
+ function isValidERC1271SignatureNow(
+ address signer,
+ bytes32 digest,
+ bytes memory signature
+ ) internal view returns (bool) {
+ (bool success, bytes memory result) = signer.staticcall(
+ abi.encodeWithSelector(
+ IERC1271.isValidSignature.selector,
+ digest,
+ signature
+ )
+ );
+ return (success &&
+ result.length >= 32 &&
+ abi.decode(result, (bytes32)) ==
+ bytes32(IERC1271.isValidSignature.selector));
+ }
+
+ /**
+ * @dev Checks if the input address is a smart contract.
+ */
+ function isContract(address addr) internal view returns (bool) {
+ uint256 size;
+ assembly {
+ size := extcodesize(addr)
+ }
+ return size > 0;
+ }
+}
diff --git a/contracts/v1.1/FiatTokenV1_1.sol b/contracts/v1.1/FiatTokenV1_1.sol
index a92a54fc4..b111c50a5 100644
--- a/contracts/v1.1/FiatTokenV1_1.sol
+++ b/contracts/v1.1/FiatTokenV1_1.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/v1.1/Rescuable.sol b/contracts/v1.1/Rescuable.sol
index 5af835e9a..11cfb9f2f 100644
--- a/contracts/v1.1/Rescuable.sol
+++ b/contracts/v1.1/Rescuable.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
@@ -66,8 +60,8 @@ contract Rescuable is Ownable {
}
/**
- * @notice Assign the rescuer role to a given address.
- * @param newRescuer New rescuer's address
+ * @notice Updates the rescuer address.
+ * @param newRescuer The address of the new rescuer.
*/
function updateRescuer(address newRescuer) external onlyOwner {
require(
diff --git a/contracts/v1/AbstractFiatTokenV1.sol b/contracts/v1/AbstractFiatTokenV1.sol
index 89e3906e4..5c8acb883 100644
--- a/contracts/v1/AbstractFiatTokenV1.sol
+++ b/contracts/v1/AbstractFiatTokenV1.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/v1/Blacklistable.sol b/contracts/v1/Blacklistable.sol
index c1827e836..f289aa64f 100644
--- a/contracts/v1/Blacklistable.sol
+++ b/contracts/v1/Blacklistable.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
@@ -30,16 +24,16 @@ import { Ownable } from "./Ownable.sol";
* @title Blacklistable Token
* @dev Allows accounts to be blacklisted by a "blacklister" role
*/
-contract Blacklistable is Ownable {
+abstract contract Blacklistable is Ownable {
address public blacklister;
- mapping(address => bool) internal blacklisted;
+ mapping(address => bool) internal _deprecatedBlacklisted;
event Blacklisted(address indexed _account);
event UnBlacklisted(address indexed _account);
event BlacklisterChanged(address indexed newBlacklister);
/**
- * @dev Throws if called by any account other than the blacklister
+ * @dev Throws if called by any account other than the blacklister.
*/
modifier onlyBlacklister() {
require(
@@ -50,43 +44,48 @@ contract Blacklistable is Ownable {
}
/**
- * @dev Throws if argument account is blacklisted
- * @param _account The address to check
+ * @dev Throws if argument account is blacklisted.
+ * @param _account The address to check.
*/
modifier notBlacklisted(address _account) {
require(
- !blacklisted[_account],
+ !_isBlacklisted(_account),
"Blacklistable: account is blacklisted"
);
_;
}
/**
- * @dev Checks if account is blacklisted
- * @param _account The address to check
+ * @notice Checks if account is blacklisted.
+ * @param _account The address to check.
+ * @return True if the account is blacklisted, false if the account is not blacklisted.
*/
function isBlacklisted(address _account) external view returns (bool) {
- return blacklisted[_account];
+ return _isBlacklisted(_account);
}
/**
- * @dev Adds account to blacklist
- * @param _account The address to blacklist
+ * @notice Adds account to blacklist.
+ * @param _account The address to blacklist.
*/
function blacklist(address _account) external onlyBlacklister {
- blacklisted[_account] = true;
+ _blacklist(_account);
emit Blacklisted(_account);
}
/**
- * @dev Removes account from blacklist
- * @param _account The address to remove from the blacklist
+ * @notice Removes account from blacklist.
+ * @param _account The address to remove from the blacklist.
*/
function unBlacklist(address _account) external onlyBlacklister {
- blacklisted[_account] = false;
+ _unBlacklist(_account);
emit UnBlacklisted(_account);
}
+ /**
+ * @notice Updates the blacklister address.
+ * @param _newBlacklister The address of the new blacklister.
+ */
function updateBlacklister(address _newBlacklister) external onlyOwner {
require(
_newBlacklister != address(0),
@@ -95,4 +94,27 @@ contract Blacklistable is Ownable {
blacklister = _newBlacklister;
emit BlacklisterChanged(blacklister);
}
+
+ /**
+ * @dev Checks if account is blacklisted.
+ * @param _account The address to check.
+ * @return true if the account is blacklisted, false otherwise.
+ */
+ function _isBlacklisted(address _account)
+ internal
+ virtual
+ view
+ returns (bool);
+
+ /**
+ * @dev Helper method that blacklists an account.
+ * @param _account The address to blacklist.
+ */
+ function _blacklist(address _account) internal virtual;
+
+ /**
+ * @dev Helper method that unblacklists an account.
+ * @param _account The address to unblacklist.
+ */
+ function _unBlacklist(address _account) internal virtual;
}
diff --git a/contracts/v1/FiatTokenProxy.sol b/contracts/v1/FiatTokenProxy.sol
index 4f6215b07..9f4962c74 100644
--- a/contracts/v1/FiatTokenProxy.sol
+++ b/contracts/v1/FiatTokenProxy.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/v1/FiatTokenV1.sol b/contracts/v1/FiatTokenV1.sol
index 1820842d1..014c139ef 100644
--- a/contracts/v1/FiatTokenV1.sol
+++ b/contracts/v1/FiatTokenV1.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
@@ -44,7 +38,10 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
address public masterMinter;
bool internal initialized;
- mapping(address => uint256) internal balances;
+ /// @dev A mapping that stores the balance and blacklist states for a given address.
+ /// The first bit defines whether the address is blacklisted (1 if blacklisted, 0 otherwise).
+ /// The last 255 bits define the balance for the address.
+ mapping(address => uint256) internal balanceAndBlacklistStates;
mapping(address => mapping(address => uint256)) internal allowed;
uint256 internal totalSupply_ = 0;
mapping(address => bool) internal minters;
@@ -56,6 +53,17 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
event MinterRemoved(address indexed oldMinter);
event MasterMinterChanged(address indexed newMasterMinter);
+ /**
+ * @notice Initializes the fiat token contract.
+ * @param tokenName The name of the fiat token.
+ * @param tokenSymbol The symbol of the fiat token.
+ * @param tokenCurrency The fiat currency that the token represents.
+ * @param tokenDecimals The number of decimals that the token uses.
+ * @param newMasterMinter The masterMinter address for the fiat token.
+ * @param newPauser The pauser address for the fiat token.
+ * @param newBlacklister The blacklister address for the fiat token.
+ * @param newOwner The owner of the fiat token.
+ */
function initialize(
string memory tokenName,
string memory tokenSymbol,
@@ -96,7 +104,7 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @dev Throws if called by any account other than a minter
+ * @dev Throws if called by any account other than a minter.
*/
modifier onlyMinters() {
require(minters[msg.sender], "FiatToken: caller is not a minter");
@@ -104,11 +112,11 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @dev Function to mint tokens
+ * @notice Mints fiat tokens to an address.
* @param _to The address that will receive the minted tokens.
* @param _amount The amount of tokens to mint. Must be less than or equal
* to the minterAllowance of the caller.
- * @return A boolean that indicates if the operation was successful.
+ * @return True if the operation was successful.
*/
function mint(address _to, uint256 _amount)
external
@@ -128,7 +136,7 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
);
totalSupply_ = totalSupply_.add(_amount);
- balances[_to] = balances[_to].add(_amount);
+ _setBalance(_to, _balanceOf(_to).add(_amount));
minterAllowed[msg.sender] = mintingAllowedAmount.sub(_amount);
emit Mint(msg.sender, _to, _amount);
emit Transfer(address(0), _to, _amount);
@@ -147,27 +155,29 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @dev Get minter allowance for an account
- * @param minter The address of the minter
+ * @notice Gets the minter allowance for an account.
+ * @param minter The address to check.
+ * @return The remaining minter allowance for the account.
*/
function minterAllowance(address minter) external view returns (uint256) {
return minterAllowed[minter];
}
/**
- * @dev Checks if account is a minter
- * @param account The address to check
+ * @notice Checks if an account is a minter.
+ * @param account The address to check.
+ * @return True if the account is a minter, false if the account is not a minter.
*/
function isMinter(address account) external view returns (bool) {
return minters[account];
}
/**
- * @notice Amount of remaining tokens spender is allowed to transfer on
- * behalf of the token owner
- * @param owner Token owner's address
- * @param spender Spender's address
- * @return Allowance amount
+ * @notice Gets the remaining amount of fiat tokens a spender is allowed to transfer on
+ * behalf of the token owner.
+ * @param owner The token owner's address.
+ * @param spender The spender's address.
+ * @return The remaining allowance.
*/
function allowance(address owner, address spender)
external
@@ -179,15 +189,17 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @dev Get totalSupply of token
+ * @notice Gets the totalSupply of the fiat token.
+ * @return The totalSupply of the fiat token.
*/
function totalSupply() external override view returns (uint256) {
return totalSupply_;
}
/**
- * @dev Get token balance of an account
- * @param account address The account
+ * @notice Gets the fiat token balance of an account.
+ * @param account The address to check.
+ * @return balance The fiat token balance of the account.
*/
function balanceOf(address account)
external
@@ -195,18 +207,18 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
view
returns (uint256)
{
- return balances[account];
+ return _balanceOf(account);
}
/**
- * @notice Set spender's allowance over the caller's tokens to be a given
- * value.
- * @param spender Spender's address
- * @param value Allowance amount
- * @return True if successful
+ * @notice Sets a fiat token allowance for a spender to spend on behalf of the caller.
+ * @param spender The spender's address.
+ * @param value The allowance amount.
+ * @return True if the operation was successful.
*/
function approve(address spender, uint256 value)
external
+ virtual
override
whenNotPaused
notBlacklisted(msg.sender)
@@ -218,10 +230,10 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @dev Internal function to set allowance
- * @param owner Token owner's address
- * @param spender Spender's address
- * @param value Allowance amount
+ * @dev Internal function to set allowance.
+ * @param owner Token owner's address.
+ * @param spender Spender's address.
+ * @param value Allowance amount.
*/
function _approve(
address owner,
@@ -235,11 +247,12 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @notice Transfer tokens by spending allowance
- * @param from Payer's address
- * @param to Payee's address
- * @param value Transfer amount
- * @return True if successful
+ * @notice Transfers tokens from an address to another by spending the caller's allowance.
+ * @dev The caller must have some fiat token allowance on the payer's tokens.
+ * @param from Payer's address.
+ * @param to Payee's address.
+ * @param value Transfer amount.
+ * @return True if the operation was successful.
*/
function transferFrom(
address from,
@@ -264,10 +277,10 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @notice Transfer tokens from the caller
- * @param to Payee's address
- * @param value Transfer amount
- * @return True if successful
+ * @notice Transfers tokens from the caller.
+ * @param to Payee's address.
+ * @param value Transfer amount.
+ * @return True if the operation was successful.
*/
function transfer(address to, uint256 value)
external
@@ -282,10 +295,10 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @notice Internal function to process transfers
- * @param from Payer's address
- * @param to Payee's address
- * @param value Transfer amount
+ * @dev Internal function to process transfers.
+ * @param from Payer's address.
+ * @param to Payee's address.
+ * @param value Transfer amount.
*/
function _transfer(
address from,
@@ -295,19 +308,19 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(
- value <= balances[from],
+ value <= _balanceOf(from),
"ERC20: transfer amount exceeds balance"
);
- balances[from] = balances[from].sub(value);
- balances[to] = balances[to].add(value);
+ _setBalance(from, _balanceOf(from).sub(value));
+ _setBalance(to, _balanceOf(to).add(value));
emit Transfer(from, to, value);
}
/**
- * @dev Function to add/update a new minter
- * @param minter The address of the minter
- * @param minterAllowedAmount The minting amount allowed for the minter
+ * @notice Adds or updates a new minter with a mint allowance.
+ * @param minter The address of the minter.
+ * @param minterAllowedAmount The minting amount allowed for the minter.
* @return True if the operation was successful.
*/
function configureMinter(address minter, uint256 minterAllowedAmount)
@@ -323,8 +336,8 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @dev Function to remove a minter
- * @param minter The address of the minter to remove
+ * @notice Removes a minter.
+ * @param minter The address of the minter to remove.
* @return True if the operation was successful.
*/
function removeMinter(address minter)
@@ -339,10 +352,10 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
}
/**
- * @dev allows a minter to burn some of its own tokens
- * Validates that caller is a minter and that sender is not blacklisted
- * amount is less than or equal to the minter's account balance
- * @param _amount uint256 the amount of tokens to be burned
+ * @notice Allows a minter to burn some of its own tokens.
+ * @dev The caller must be a minter, must not be blacklisted, and the amount to burn
+ * should be less than or equal to the account's balance.
+ * @param _amount the amount of tokens to be burned.
*/
function burn(uint256 _amount)
external
@@ -350,16 +363,20 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
onlyMinters
notBlacklisted(msg.sender)
{
- uint256 balance = balances[msg.sender];
+ uint256 balance = _balanceOf(msg.sender);
require(_amount > 0, "FiatToken: burn amount not greater than 0");
require(balance >= _amount, "FiatToken: burn amount exceeds balance");
totalSupply_ = totalSupply_.sub(_amount);
- balances[msg.sender] = balance.sub(_amount);
+ _setBalance(msg.sender, balance.sub(_amount));
emit Burn(msg.sender, _amount);
emit Transfer(msg.sender, address(0), _amount);
}
+ /**
+ * @notice Updates the master minter address.
+ * @param _newMasterMinter The address of the new master minter.
+ */
function updateMasterMinter(address _newMasterMinter) external onlyOwner {
require(
_newMasterMinter != address(0),
@@ -368,4 +385,66 @@ contract FiatTokenV1 is AbstractFiatTokenV1, Ownable, Pausable, Blacklistable {
masterMinter = _newMasterMinter;
emit MasterMinterChanged(masterMinter);
}
+
+ /**
+ * @inheritdoc Blacklistable
+ */
+ function _blacklist(address _account) internal override {
+ _setBlacklistState(_account, true);
+ }
+
+ /**
+ * @inheritdoc Blacklistable
+ */
+ function _unBlacklist(address _account) internal override {
+ _setBlacklistState(_account, false);
+ }
+
+ /**
+ * @dev Helper method that sets the blacklist state of an account.
+ * @param _account The address of the account.
+ * @param _shouldBlacklist True if the account should be blacklisted, false if the account should be unblacklisted.
+ */
+ function _setBlacklistState(address _account, bool _shouldBlacklist)
+ internal
+ virtual
+ {
+ _deprecatedBlacklisted[_account] = _shouldBlacklist;
+ }
+
+ /**
+ * @dev Helper method that sets the balance of an account.
+ * @param _account The address of the account.
+ * @param _balance The new fiat token balance of the account.
+ */
+ function _setBalance(address _account, uint256 _balance) internal virtual {
+ balanceAndBlacklistStates[_account] = _balance;
+ }
+
+ /**
+ * @inheritdoc Blacklistable
+ */
+ function _isBlacklisted(address _account)
+ internal
+ virtual
+ override
+ view
+ returns (bool)
+ {
+ return _deprecatedBlacklisted[_account];
+ }
+
+ /**
+ * @dev Helper method to obtain the balance of an account.
+ * @param _account The address of the account.
+ * @return The fiat token balance of the account.
+ */
+ function _balanceOf(address _account)
+ internal
+ virtual
+ view
+ returns (uint256)
+ {
+ return balanceAndBlacklistStates[_account];
+ }
}
diff --git a/contracts/v1/Ownable.sol b/contracts/v1/Ownable.sol
index b830eee48..3e90f61d2 100644
--- a/contracts/v1/Ownable.sol
+++ b/contracts/v1/Ownable.sol
@@ -22,6 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+
pragma solidity 0.6.12;
/**
diff --git a/contracts/v1/Pausable.sol b/contracts/v1/Pausable.sol
index d814a729c..51c120349 100644
--- a/contracts/v1/Pausable.sol
+++ b/contracts/v1/Pausable.sol
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2016 Smart Contract Solutions, Inc.
- * Copyright (c) 2018-2020 CENTRE SECZ0
+ * Copyright (c) 2018-2020 CENTRE SECZ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -81,7 +81,8 @@ contract Pausable is Ownable {
}
/**
- * @dev update the pauser role
+ * @notice Updates the pauser address.
+ * @param _newPauser The address of the new pauser.
*/
function updatePauser(address _newPauser) external onlyOwner {
require(
diff --git a/contracts/v2/AbstractFiatTokenV2.sol b/contracts/v2/AbstractFiatTokenV2.sol
index f70a5d49d..1d00a6a3a 100644
--- a/contracts/v2/AbstractFiatTokenV2.sol
+++ b/contracts/v2/AbstractFiatTokenV2.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/v2/EIP2612.sol b/contracts/v2/EIP2612.sol
new file mode 100644
index 000000000..ecc278e8f
--- /dev/null
+++ b/contracts/v2/EIP2612.sol
@@ -0,0 +1,113 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { AbstractFiatTokenV2 } from "./AbstractFiatTokenV2.sol";
+import { EIP712Domain } from "./EIP712Domain.sol";
+import { MessageHashUtils } from "../util/MessageHashUtils.sol";
+import { SignatureChecker } from "../util/SignatureChecker.sol";
+
+/**
+ * @title EIP-2612
+ * @notice Provide internal implementation for gas-abstracted approvals
+ */
+abstract contract EIP2612 is AbstractFiatTokenV2, EIP712Domain {
+ // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
+ bytes32
+ public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
+
+ mapping(address => uint256) private _permitNonces;
+
+ /**
+ * @notice Nonces for permit
+ * @param owner Token owner's address (Authorizer)
+ * @return Next nonce
+ */
+ function nonces(address owner) external view returns (uint256) {
+ return _permitNonces[owner];
+ }
+
+ /**
+ * @notice Verify a signed approval permit and execute if valid
+ * @param owner Token owner's address (Authorizer)
+ * @param spender Spender's address
+ * @param value Amount of allowance
+ * @param deadline The time at which the signature expires (unix time), or max uint256 value to signal no expiration
+ * @param v v of the signature
+ * @param r r of the signature
+ * @param s s of the signature
+ */
+ function _permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+ ) internal {
+ _permit(owner, spender, value, deadline, abi.encodePacked(r, s, v));
+ }
+
+ /**
+ * @notice Verify a signed approval permit and execute if valid
+ * @dev EOA wallet signatures should be packed in the order of r, s, v.
+ * @param owner Token owner's address (Authorizer)
+ * @param spender Spender's address
+ * @param value Amount of allowance
+ * @param deadline The time at which the signature expires (unix time), or max uint256 value to signal no expiration
+ * @param signature Signature byte array signed by an EOA wallet or a contract wallet
+ */
+ function _permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ bytes memory signature
+ ) internal {
+ require(
+ deadline == type(uint256).max || deadline >= now,
+ "FiatTokenV2: permit is expired"
+ );
+
+ bytes32 typedDataHash = MessageHashUtils.toTypedDataHash(
+ _domainSeparator(),
+ keccak256(
+ abi.encode(
+ PERMIT_TYPEHASH,
+ owner,
+ spender,
+ value,
+ _permitNonces[owner]++,
+ deadline
+ )
+ )
+ );
+ require(
+ SignatureChecker.isValidSignatureNow(
+ owner,
+ typedDataHash,
+ signature
+ ),
+ "EIP2612: invalid signature"
+ );
+
+ _approve(owner, spender, value);
+ }
+}
diff --git a/contracts/v2/EIP3009.sol b/contracts/v2/EIP3009.sol
new file mode 100644
index 000000000..7fe670f36
--- /dev/null
+++ b/contracts/v2/EIP3009.sol
@@ -0,0 +1,338 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { AbstractFiatTokenV2 } from "./AbstractFiatTokenV2.sol";
+import { EIP712Domain } from "./EIP712Domain.sol";
+import { SignatureChecker } from "../util/SignatureChecker.sol";
+import { MessageHashUtils } from "../util/MessageHashUtils.sol";
+
+/**
+ * @title EIP-3009
+ * @notice Provide internal implementation for gas-abstracted transfers
+ * @dev Contracts that inherit from this must wrap these with publicly
+ * accessible functions, optionally adding modifiers where necessary
+ */
+abstract contract EIP3009 is AbstractFiatTokenV2, EIP712Domain {
+ // keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
+ bytes32
+ public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;
+
+ // keccak256("ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
+ bytes32
+ public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH = 0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;
+
+ // keccak256("CancelAuthorization(address authorizer,bytes32 nonce)")
+ bytes32
+ public constant CANCEL_AUTHORIZATION_TYPEHASH = 0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;
+
+ /**
+ * @dev authorizer address => nonce => bool (true if nonce is used)
+ */
+ mapping(address => mapping(bytes32 => bool)) private _authorizationStates;
+
+ event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
+ event AuthorizationCanceled(
+ address indexed authorizer,
+ bytes32 indexed nonce
+ );
+
+ /**
+ * @notice Returns the state of an authorization
+ * @dev Nonces are randomly generated 32-byte data unique to the
+ * authorizer's address
+ * @param authorizer Authorizer's address
+ * @param nonce Nonce of the authorization
+ * @return True if the nonce is used
+ */
+ function authorizationState(address authorizer, bytes32 nonce)
+ external
+ view
+ returns (bool)
+ {
+ return _authorizationStates[authorizer][nonce];
+ }
+
+ /**
+ * @notice Execute a transfer with a signed authorization
+ * @param from Payer's address (Authorizer)
+ * @param to Payee's address
+ * @param value Amount to be transferred
+ * @param validAfter The time after which this is valid (unix time)
+ * @param validBefore The time before which this is valid (unix time)
+ * @param nonce Unique nonce
+ * @param v v of the signature
+ * @param r r of the signature
+ * @param s s of the signature
+ */
+ function _transferWithAuthorization(
+ address from,
+ address to,
+ uint256 value,
+ uint256 validAfter,
+ uint256 validBefore,
+ bytes32 nonce,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+ ) internal {
+ _transferWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ abi.encodePacked(r, s, v)
+ );
+ }
+
+ /**
+ * @notice Execute a transfer with a signed authorization
+ * @dev EOA wallet signatures should be packed in the order of r, s, v.
+ * @param from Payer's address (Authorizer)
+ * @param to Payee's address
+ * @param value Amount to be transferred
+ * @param validAfter The time after which this is valid (unix time)
+ * @param validBefore The time before which this is valid (unix time)
+ * @param nonce Unique nonce
+ * @param signature Signature byte array produced by an EOA wallet or a contract wallet
+ */
+ function _transferWithAuthorization(
+ address from,
+ address to,
+ uint256 value,
+ uint256 validAfter,
+ uint256 validBefore,
+ bytes32 nonce,
+ bytes memory signature
+ ) internal {
+ _requireValidAuthorization(from, nonce, validAfter, validBefore);
+ _requireValidSignature(
+ from,
+ keccak256(
+ abi.encode(
+ TRANSFER_WITH_AUTHORIZATION_TYPEHASH,
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce
+ )
+ ),
+ signature
+ );
+
+ _markAuthorizationAsUsed(from, nonce);
+ _transfer(from, to, value);
+ }
+
+ /**
+ * @notice Receive a transfer with a signed authorization from the payer
+ * @dev This has an additional check to ensure that the payee's address
+ * matches the caller of this function to prevent front-running attacks.
+ * @param from Payer's address (Authorizer)
+ * @param to Payee's address
+ * @param value Amount to be transferred
+ * @param validAfter The time after which this is valid (unix time)
+ * @param validBefore The time before which this is valid (unix time)
+ * @param nonce Unique nonce
+ * @param v v of the signature
+ * @param r r of the signature
+ * @param s s of the signature
+ */
+ function _receiveWithAuthorization(
+ address from,
+ address to,
+ uint256 value,
+ uint256 validAfter,
+ uint256 validBefore,
+ bytes32 nonce,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+ ) internal {
+ _receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ abi.encodePacked(r, s, v)
+ );
+ }
+
+ /**
+ * @notice Receive a transfer with a signed authorization from the payer
+ * @dev This has an additional check to ensure that the payee's address
+ * matches the caller of this function to prevent front-running attacks.
+ * EOA wallet signatures should be packed in the order of r, s, v.
+ * @param from Payer's address (Authorizer)
+ * @param to Payee's address
+ * @param value Amount to be transferred
+ * @param validAfter The time after which this is valid (unix time)
+ * @param validBefore The time before which this is valid (unix time)
+ * @param nonce Unique nonce
+ * @param signature Signature byte array produced by an EOA wallet or a contract wallet
+ */
+ function _receiveWithAuthorization(
+ address from,
+ address to,
+ uint256 value,
+ uint256 validAfter,
+ uint256 validBefore,
+ bytes32 nonce,
+ bytes memory signature
+ ) internal {
+ require(to == msg.sender, "FiatTokenV2: caller must be the payee");
+ _requireValidAuthorization(from, nonce, validAfter, validBefore);
+ _requireValidSignature(
+ from,
+ keccak256(
+ abi.encode(
+ RECEIVE_WITH_AUTHORIZATION_TYPEHASH,
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce
+ )
+ ),
+ signature
+ );
+
+ _markAuthorizationAsUsed(from, nonce);
+ _transfer(from, to, value);
+ }
+
+ /**
+ * @notice Attempt to cancel an authorization
+ * @param authorizer Authorizer's address
+ * @param nonce Nonce of the authorization
+ * @param v v of the signature
+ * @param r r of the signature
+ * @param s s of the signature
+ */
+ function _cancelAuthorization(
+ address authorizer,
+ bytes32 nonce,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+ ) internal {
+ _cancelAuthorization(authorizer, nonce, abi.encodePacked(r, s, v));
+ }
+
+ /**
+ * @notice Attempt to cancel an authorization
+ * @dev EOA wallet signatures should be packed in the order of r, s, v.
+ * @param authorizer Authorizer's address
+ * @param nonce Nonce of the authorization
+ * @param signature Signature byte array produced by an EOA wallet or a contract wallet
+ */
+ function _cancelAuthorization(
+ address authorizer,
+ bytes32 nonce,
+ bytes memory signature
+ ) internal {
+ _requireUnusedAuthorization(authorizer, nonce);
+ _requireValidSignature(
+ authorizer,
+ keccak256(
+ abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer, nonce)
+ ),
+ signature
+ );
+
+ _authorizationStates[authorizer][nonce] = true;
+ emit AuthorizationCanceled(authorizer, nonce);
+ }
+
+ /**
+ * @notice Validates that signature against input data struct
+ * @param signer Signer's address
+ * @param dataHash Hash of encoded data struct
+ * @param signature Signature byte array produced by an EOA wallet or a contract wallet
+ */
+ function _requireValidSignature(
+ address signer,
+ bytes32 dataHash,
+ bytes memory signature
+ ) private view {
+ require(
+ SignatureChecker.isValidSignatureNow(
+ signer,
+ MessageHashUtils.toTypedDataHash(_domainSeparator(), dataHash),
+ signature
+ ),
+ "FiatTokenV2: invalid signature"
+ );
+ }
+
+ /**
+ * @notice Check that an authorization is unused
+ * @param authorizer Authorizer's address
+ * @param nonce Nonce of the authorization
+ */
+ function _requireUnusedAuthorization(address authorizer, bytes32 nonce)
+ private
+ view
+ {
+ require(
+ !_authorizationStates[authorizer][nonce],
+ "FiatTokenV2: authorization is used or canceled"
+ );
+ }
+
+ /**
+ * @notice Check that authorization is valid
+ * @param authorizer Authorizer's address
+ * @param nonce Nonce of the authorization
+ * @param validAfter The time after which this is valid (unix time)
+ * @param validBefore The time before which this is valid (unix time)
+ */
+ function _requireValidAuthorization(
+ address authorizer,
+ bytes32 nonce,
+ uint256 validAfter,
+ uint256 validBefore
+ ) private view {
+ require(
+ now > validAfter,
+ "FiatTokenV2: authorization is not yet valid"
+ );
+ require(now < validBefore, "FiatTokenV2: authorization is expired");
+ _requireUnusedAuthorization(authorizer, nonce);
+ }
+
+ /**
+ * @notice Mark an authorization as used
+ * @param authorizer Authorizer's address
+ * @param nonce Nonce of the authorization
+ */
+ function _markAuthorizationAsUsed(address authorizer, bytes32 nonce)
+ private
+ {
+ _authorizationStates[authorizer][nonce] = true;
+ emit AuthorizationUsed(authorizer, nonce);
+ }
+}
diff --git a/contracts/v2/EIP712Domain.sol b/contracts/v2/EIP712Domain.sol
index 2b9907348..6ebf81b22 100644
--- a/contracts/v2/EIP712Domain.sol
+++ b/contracts/v2/EIP712Domain.sol
@@ -1,35 +1,46 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
+// solhint-disable func-name-mixedcase
+
/**
* @title EIP712 Domain
*/
contract EIP712Domain {
+ // was originally DOMAIN_SEPARATOR
+ // but that has been moved to a method so we can override it in V2_2+
+ bytes32 internal _DEPRECATED_CACHED_DOMAIN_SEPARATOR;
+
+ /**
+ * @notice Get the EIP712 Domain Separator.
+ * @return The bytes32 EIP712 domain separator.
+ */
+ function DOMAIN_SEPARATOR() external view returns (bytes32) {
+ return _domainSeparator();
+ }
+
/**
- * @dev EIP712 Domain Separator
+ * @dev Internal method to get the EIP712 Domain Separator.
+ * @return The bytes32 EIP712 domain separator.
*/
- bytes32 public DOMAIN_SEPARATOR;
+ function _domainSeparator() internal virtual view returns (bytes32) {
+ return _DEPRECATED_CACHED_DOMAIN_SEPARATOR;
+ }
}
diff --git a/contracts/v2/FiatTokenUtil.sol b/contracts/v2/FiatTokenUtil.sol
index d4ba5466f..92d689383 100644
--- a/contracts/v2/FiatTokenUtil.sol
+++ b/contracts/v2/FiatTokenUtil.sol
@@ -1,25 +1,19 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
diff --git a/contracts/v2/FiatTokenV2.sol b/contracts/v2/FiatTokenV2.sol
index a0067050e..d45836c10 100644
--- a/contracts/v2/FiatTokenV2.sol
+++ b/contracts/v2/FiatTokenV2.sol
@@ -1,58 +1,48 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
import { FiatTokenV1_1 } from "../v1.1/FiatTokenV1_1.sol";
-import { AbstractFiatTokenV2 } from "./AbstractFiatTokenV2.sol";
import { EIP712 } from "../util/EIP712.sol";
-import { EIP712Domain } from "./EIP712Domain.sol";
-import { GasAbstraction } from "./GasAbstraction.sol";
-import { Permit } from "./Permit.sol";
+import { EIP3009 } from "./EIP3009.sol";
+import { EIP2612 } from "./EIP2612.sol";
/**
* @title FiatToken V2
* @notice ERC20 Token backed by fiat reserves, version 2
*/
-contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
- bool internal _initializedV2;
+contract FiatTokenV2 is FiatTokenV1_1, EIP3009, EIP2612 {
+ uint8 internal _initializedVersion;
/**
- * @notice Initialize V2 contract
- * @dev When upgrading to V2, this function must also be invoked by using
- * upgradeToAndCall instead of upgradeTo, or by calling both from a contract
- * in a single transaction.
+ * @notice Initialize v2
* @param newName New token name
*/
function initializeV2(string calldata newName) external {
- require(
- !_initializedV2,
- "FiatTokenV2: contract is already initialized"
- );
+ // solhint-disable-next-line reason-string
+ require(initialized && _initializedVersion == 0);
name = newName;
- DOMAIN_SEPARATOR = EIP712.makeDomainSeparator(newName, "2");
- _initializedV2 = true;
+ _DEPRECATED_CACHED_DOMAIN_SEPARATOR = EIP712.makeDomainSeparator(
+ newName,
+ "2"
+ );
+ _initializedVersion = 1;
}
/**
@@ -63,6 +53,7 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
*/
function increaseAllowance(address spender, uint256 increment)
external
+ virtual
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(spender)
@@ -80,6 +71,7 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
*/
function decreaseAllowance(address spender, uint256 decrement)
external
+ virtual
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(spender)
@@ -126,10 +118,12 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
}
/**
- * @notice Update allowance with a signed authorization
- * @param owner Token owner's address (Authorizer)
- * @param spender Spender's address
- * @param value Amount of allowance
+ * @notice Receive a transfer with a signed authorization from the payer
+ * @dev This has an additional check to ensure that the payee's address
+ * matches the caller of this function to prevent front-running attacks.
+ * @param from Payer's address (Authorizer)
+ * @param to Payee's address
+ * @param value Amount to be transferred
* @param validAfter The time after which this is valid (unix time)
* @param validBefore The time before which this is valid (unix time)
* @param nonce Unique nonce
@@ -137,9 +131,9 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
* @param r r of the signature
* @param s s of the signature
*/
- function approveWithAuthorization(
- address owner,
- address spender,
+ function receiveWithAuthorization(
+ address from,
+ address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
@@ -147,10 +141,10 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
uint8 v,
bytes32 r,
bytes32 s
- ) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
- _approveWithAuthorization(
- owner,
- spender,
+ ) external whenNotPaused notBlacklisted(from) notBlacklisted(to) {
+ _receiveWithAuthorization(
+ from,
+ to,
value,
validAfter,
validBefore,
@@ -161,78 +155,6 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
);
}
- /**
- * @notice Increase allowance with a signed authorization
- * @param owner Token owner's address (Authorizer)
- * @param spender Spender's address
- * @param increment Amount of increase in allowance
- * @param validAfter The time after which this is valid (unix time)
- * @param validBefore The time before which this is valid (unix time)
- * @param nonce Unique nonce
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function increaseAllowanceWithAuthorization(
- address owner,
- address spender,
- uint256 increment,
- uint256 validAfter,
- uint256 validBefore,
- bytes32 nonce,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
- _increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s
- );
- }
-
- /**
- * @notice Decrease allowance with a signed authorization
- * @param owner Token owner's address (Authorizer)
- * @param spender Spender's address
- * @param decrement Amount of decrease in allowance
- * @param validAfter The time after which this is valid (unix time)
- * @param validBefore The time before which this is valid (unix time)
- * @param nonce Unique nonce
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function decreaseAllowanceWithAuthorization(
- address owner,
- address spender,
- uint256 decrement,
- uint256 validAfter,
- uint256 validBefore,
- bytes32 nonce,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
- _decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s
- );
- }
-
/**
* @notice Attempt to cancel an authorization
* @dev Works only if the authorization is not yet used.
@@ -257,7 +179,7 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
* @param owner Token owner's address (Authorizer)
* @param spender Spender's address
* @param value Amount of allowance
- * @param deadline Expiration time, seconds since the epoch
+ * @param deadline The time at which the signature expires (unix time), or max uint256 value to signal no expiration
* @param v v of the signature
* @param r r of the signature
* @param s s of the signature
@@ -270,12 +192,18 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
uint8 v,
bytes32 r,
bytes32 s
- ) external whenNotPaused notBlacklisted(owner) notBlacklisted(spender) {
+ )
+ external
+ virtual
+ whenNotPaused
+ notBlacklisted(owner)
+ notBlacklisted(spender)
+ {
_permit(owner, spender, value, deadline, v, r, s);
}
/**
- * @notice Internal function to increase the allowance by a given increment
+ * @dev Internal function to increase the allowance by a given increment
* @param owner Token owner's address
* @param spender Spender's address
* @param increment Amount of increase
@@ -289,7 +217,7 @@ contract FiatTokenV2 is FiatTokenV1_1, GasAbstraction, Permit {
}
/**
- * @notice Internal function to decrease the allowance by a given decrement
+ * @dev Internal function to decrease the allowance by a given decrement
* @param owner Token owner's address
* @param spender Spender's address
* @param decrement Amount of decrease
diff --git a/contracts/v2/FiatTokenV2_1.sol b/contracts/v2/FiatTokenV2_1.sol
new file mode 100644
index 000000000..d9b5908f8
--- /dev/null
+++ b/contracts/v2/FiatTokenV2_1.sol
@@ -0,0 +1,54 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenV2 } from "./FiatTokenV2.sol";
+
+// solhint-disable func-name-mixedcase
+
+/**
+ * @title FiatToken V2.1
+ * @notice ERC20 Token backed by fiat reserves, version 2.1
+ */
+contract FiatTokenV2_1 is FiatTokenV2 {
+ /**
+ * @notice Initialize v2.1
+ * @param lostAndFound The address to which the locked funds are sent
+ */
+ function initializeV2_1(address lostAndFound) external {
+ // solhint-disable-next-line reason-string
+ require(_initializedVersion == 1);
+
+ uint256 lockedAmount = _balanceOf(address(this));
+ if (lockedAmount > 0) {
+ _transfer(address(this), lostAndFound, lockedAmount);
+ }
+ _blacklist(address(this));
+
+ _initializedVersion = 2;
+ }
+
+ /**
+ * @notice Version string for the EIP712 domain separator
+ * @return Version string
+ */
+ function version() external pure returns (string memory) {
+ return "2";
+ }
+}
diff --git a/contracts/v2/FiatTokenV2_2.sol b/contracts/v2/FiatTokenV2_2.sol
new file mode 100644
index 000000000..d29a7a278
--- /dev/null
+++ b/contracts/v2/FiatTokenV2_2.sol
@@ -0,0 +1,309 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { EIP712Domain } from "./EIP712Domain.sol"; // solhint-disable-line no-unused-import
+import { Blacklistable } from "../v1/Blacklistable.sol"; // solhint-disable-line no-unused-import
+import { FiatTokenV1 } from "../v1/FiatTokenV1.sol"; // solhint-disable-line no-unused-import
+import { FiatTokenV2 } from "./FiatTokenV2.sol"; // solhint-disable-line no-unused-import
+import { FiatTokenV2_1 } from "./FiatTokenV2_1.sol";
+import { EIP712 } from "../util/EIP712.sol";
+
+// solhint-disable func-name-mixedcase
+
+/**
+ * @title FiatToken V2.2
+ * @notice ERC20 Token backed by fiat reserves, version 2.2
+ */
+contract FiatTokenV2_2 is FiatTokenV2_1 {
+ /**
+ * @notice Initialize v2.2
+ * @param accountsToBlacklist A list of accounts to migrate from the old blacklist
+ * @param newSymbol New token symbol
+ * data structure to the new blacklist data structure.
+ */
+ function initializeV2_2(
+ address[] calldata accountsToBlacklist,
+ string calldata newSymbol
+ ) external {
+ // solhint-disable-next-line reason-string
+ require(_initializedVersion == 2);
+
+ // Update fiat token symbol
+ symbol = newSymbol;
+
+ // Add previously blacklisted accounts to the new blacklist data structure
+ // and remove them from the old blacklist data structure.
+ for (uint256 i = 0; i < accountsToBlacklist.length; i++) {
+ require(
+ _deprecatedBlacklisted[accountsToBlacklist[i]],
+ "FiatTokenV2_2: Blacklisting previously unblacklisted account!"
+ );
+ _blacklist(accountsToBlacklist[i]);
+ delete _deprecatedBlacklisted[accountsToBlacklist[i]];
+ }
+ _blacklist(address(this));
+ delete _deprecatedBlacklisted[address(this)];
+
+ _initializedVersion = 3;
+ }
+
+ /**
+ * @dev Internal function to get the current chain id.
+ * @return The current chain id.
+ */
+ function _chainId() internal virtual view returns (uint256) {
+ uint256 chainId;
+ assembly {
+ chainId := chainid()
+ }
+ return chainId;
+ }
+
+ /**
+ * @inheritdoc EIP712Domain
+ */
+ function _domainSeparator() internal override view returns (bytes32) {
+ return EIP712.makeDomainSeparator(name, "2", _chainId());
+ }
+
+ /**
+ * @notice Update allowance with a signed permit
+ * @dev EOA wallet signatures should be packed in the order of r, s, v.
+ * @param owner Token owner's address (Authorizer)
+ * @param spender Spender's address
+ * @param value Amount of allowance
+ * @param deadline The time at which the signature expires (unix time), or max uint256 value to signal no expiration
+ * @param signature Signature bytes signed by an EOA wallet or a contract wallet
+ */
+ function permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ bytes memory signature
+ ) external whenNotPaused {
+ _permit(owner, spender, value, deadline, signature);
+ }
+
+ /**
+ * @notice Execute a transfer with a signed authorization
+ * @dev EOA wallet signatures should be packed in the order of r, s, v.
+ * @param from Payer's address (Authorizer)
+ * @param to Payee's address
+ * @param value Amount to be transferred
+ * @param validAfter The time after which this is valid (unix time)
+ * @param validBefore The time before which this is valid (unix time)
+ * @param nonce Unique nonce
+ * @param signature Signature bytes signed by an EOA wallet or a contract wallet
+ */
+ function transferWithAuthorization(
+ address from,
+ address to,
+ uint256 value,
+ uint256 validAfter,
+ uint256 validBefore,
+ bytes32 nonce,
+ bytes memory signature
+ ) external whenNotPaused notBlacklisted(from) notBlacklisted(to) {
+ _transferWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ signature
+ );
+ }
+
+ /**
+ * @notice Receive a transfer with a signed authorization from the payer
+ * @dev This has an additional check to ensure that the payee's address
+ * matches the caller of this function to prevent front-running attacks.
+ * EOA wallet signatures should be packed in the order of r, s, v.
+ * @param from Payer's address (Authorizer)
+ * @param to Payee's address
+ * @param value Amount to be transferred
+ * @param validAfter The time after which this is valid (unix time)
+ * @param validBefore The time before which this is valid (unix time)
+ * @param nonce Unique nonce
+ * @param signature Signature bytes signed by an EOA wallet or a contract wallet
+ */
+ function receiveWithAuthorization(
+ address from,
+ address to,
+ uint256 value,
+ uint256 validAfter,
+ uint256 validBefore,
+ bytes32 nonce,
+ bytes memory signature
+ ) external whenNotPaused notBlacklisted(from) notBlacklisted(to) {
+ _receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ signature
+ );
+ }
+
+ /**
+ * @notice Attempt to cancel an authorization
+ * @dev Works only if the authorization is not yet used.
+ * EOA wallet signatures should be packed in the order of r, s, v.
+ * @param authorizer Authorizer's address
+ * @param nonce Nonce of the authorization
+ * @param signature Signature bytes signed by an EOA wallet or a contract wallet
+ */
+ function cancelAuthorization(
+ address authorizer,
+ bytes32 nonce,
+ bytes memory signature
+ ) external whenNotPaused {
+ _cancelAuthorization(authorizer, nonce, signature);
+ }
+
+ /**
+ * @dev Helper method that sets the blacklist state of an account on balanceAndBlacklistStates.
+ * If _shouldBlacklist is true, we apply a (1 << 255) bitmask with an OR operation on the
+ * account's balanceAndBlacklistState. This flips the high bit for the account to 1,
+ * indicating that the account is blacklisted.
+ *
+ * If _shouldBlacklist if false, we reset the account's balanceAndBlacklistStates to their
+ * balances. This clears the high bit for the account, indicating that the account is unblacklisted.
+ * @param _account The address of the account.
+ * @param _shouldBlacklist True if the account should be blacklisted, false if the account should be unblacklisted.
+ */
+ function _setBlacklistState(address _account, bool _shouldBlacklist)
+ internal
+ override
+ {
+ balanceAndBlacklistStates[_account] = _shouldBlacklist
+ ? balanceAndBlacklistStates[_account] | (1 << 255)
+ : _balanceOf(_account);
+ }
+
+ /**
+ * @dev Helper method that sets the balance of an account on balanceAndBlacklistStates.
+ * Since balances are stored in the last 255 bits of the balanceAndBlacklistStates value,
+ * we need to ensure that the updated balance does not exceed (2^255 - 1).
+ * Since blacklisted accounts' balances cannot be updated, the method will also
+ * revert if the account is blacklisted
+ * @param _account The address of the account.
+ * @param _balance The new fiat token balance of the account (max: (2^255 - 1)).
+ */
+ function _setBalance(address _account, uint256 _balance) internal override {
+ require(
+ _balance <= ((1 << 255) - 1),
+ "FiatTokenV2_2: Balance exceeds (2^255 - 1)"
+ );
+ require(
+ !_isBlacklisted(_account),
+ "FiatTokenV2_2: Account is blacklisted"
+ );
+
+ balanceAndBlacklistStates[_account] = _balance;
+ }
+
+ /**
+ * @inheritdoc Blacklistable
+ */
+ function _isBlacklisted(address _account)
+ internal
+ override
+ view
+ returns (bool)
+ {
+ return balanceAndBlacklistStates[_account] >> 255 == 1;
+ }
+
+ /**
+ * @dev Helper method to obtain the balance of an account. Since balances
+ * are stored in the last 255 bits of the balanceAndBlacklistStates value,
+ * we apply a ((1 << 255) - 1) bit bitmask with an AND operation on the
+ * balanceAndBlacklistState to obtain the balance.
+ * @param _account The address of the account.
+ * @return The fiat token balance of the account.
+ */
+ function _balanceOf(address _account)
+ internal
+ override
+ view
+ returns (uint256)
+ {
+ return balanceAndBlacklistStates[_account] & ((1 << 255) - 1);
+ }
+
+ /**
+ * @inheritdoc FiatTokenV1
+ */
+ function approve(address spender, uint256 value)
+ external
+ override
+ whenNotPaused
+ returns (bool)
+ {
+ _approve(msg.sender, spender, value);
+ return true;
+ }
+
+ /**
+ * @inheritdoc FiatTokenV2
+ */
+ function permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+ ) external override whenNotPaused {
+ _permit(owner, spender, value, deadline, v, r, s);
+ }
+
+ /**
+ * @inheritdoc FiatTokenV2
+ */
+ function increaseAllowance(address spender, uint256 increment)
+ external
+ override
+ whenNotPaused
+ returns (bool)
+ {
+ _increaseAllowance(msg.sender, spender, increment);
+ return true;
+ }
+
+ /**
+ * @inheritdoc FiatTokenV2
+ */
+ function decreaseAllowance(address spender, uint256 decrement)
+ external
+ override
+ whenNotPaused
+ returns (bool)
+ {
+ _decreaseAllowance(msg.sender, spender, decrement);
+ return true;
+ }
+}
diff --git a/contracts/v2/GasAbstraction.sol b/contracts/v2/GasAbstraction.sol
deleted file mode 100644
index e77287e1d..000000000
--- a/contracts/v2/GasAbstraction.sol
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * SPDX-License-Identifier: MIT
- *
- * Copyright (c) 2018-2020 CENTRE SECZ
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-pragma solidity 0.6.12;
-
-import { AbstractFiatTokenV2 } from "./AbstractFiatTokenV2.sol";
-import { EIP712Domain } from "./EIP712Domain.sol";
-import { EIP712 } from "../util/EIP712.sol";
-
-/**
- * @title Gas Abstraction
- * @notice Provide internal implementation for gas-abstracted transfers and
- * approvals
- * @dev Contracts that inherit from this must wrap these with publicly
- * accessible functions, optionally adding modifiers where necessary
- */
-abstract contract GasAbstraction is AbstractFiatTokenV2, EIP712Domain {
- bytes32
- public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;
- // = keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
- bytes32
- public constant APPROVE_WITH_AUTHORIZATION_TYPEHASH = 0x808c10407a796f3ef2c7ea38c0638ea9d2b8a1c63e3ca9e1f56ce84ae59df73c;
- // = keccak256("ApproveWithAuthorization(address owner,address spender,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
- bytes32
- public constant INCREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH = 0x424222bb050a1f7f14017232a5671f2680a2d3420f504bd565cf03035c53198a;
- // = keccak256("IncreaseAllowanceWithAuthorization(address owner,address spender,uint256 increment,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
- bytes32
- public constant DECREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH = 0xb70559e94cbda91958ebec07f9b65b3b490097c8d25c8dacd71105df1015b6d8;
- // = keccak256("DecreaseAllowanceWithAuthorization(address owner,address spender,uint256 decrement,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
- bytes32
- public constant CANCEL_AUTHORIZATION_TYPEHASH = 0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;
- // = keccak256("CancelAuthorization(address authorizer,bytes32 nonce)")
-
- enum AuthorizationState { Unused, Used, Canceled }
-
- /**
- * @dev authorizer address => nonce => authorization state
- */
- mapping(address => mapping(bytes32 => AuthorizationState))
- private _authorizationStates;
-
- event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
- event AuthorizationCanceled(
- address indexed authorizer,
- bytes32 indexed nonce
- );
-
- /**
- * @notice Returns the state of an authorization
- * @param authorizer Authorizer's address
- * @param nonce Nonce of the authorization
- * @return Authorization state
- */
- function authorizationState(address authorizer, bytes32 nonce)
- external
- view
- returns (AuthorizationState)
- {
- return _authorizationStates[authorizer][nonce];
- }
-
- /**
- * @notice Verify a signed transfer authorization and execute if valid
- * @param from Payer's address (Authorizer)
- * @param to Payee's address
- * @param value Amount to be transferred
- * @param validAfter The time after which this is valid (unix time)
- * @param validBefore The time before which this is valid (unix time)
- * @param nonce Unique nonce
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function _transferWithAuthorization(
- address from,
- address to,
- uint256 value,
- uint256 validAfter,
- uint256 validBefore,
- bytes32 nonce,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) internal {
- _requireValidAuthorization(from, nonce, validAfter, validBefore);
-
- bytes memory data = abi.encode(
- TRANSFER_WITH_AUTHORIZATION_TYPEHASH,
- from,
- to,
- value,
- validAfter,
- validBefore,
- nonce
- );
- require(
- EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == from,
- "FiatTokenV2: invalid signature"
- );
-
- _markAuthorizationAsUsed(from, nonce);
- _transfer(from, to, value);
- }
-
- /**
- * @notice Verify a signed authorization for an increase in the allowance
- * granted to the spender and execute if valid
- * @param owner Token owner's address (Authorizer)
- * @param spender Spender's address
- * @param increment Amount of increase in allowance
- * @param validAfter The time after which this is valid (unix time)
- * @param validBefore The time before which this is valid (unix time)
- * @param nonce Unique nonce
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function _increaseAllowanceWithAuthorization(
- address owner,
- address spender,
- uint256 increment,
- uint256 validAfter,
- uint256 validBefore,
- bytes32 nonce,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) internal {
- _requireValidAuthorization(owner, nonce, validAfter, validBefore);
-
- bytes memory data = abi.encode(
- INCREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH,
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce
- );
- require(
- EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
- "FiatTokenV2: invalid signature"
- );
-
- _markAuthorizationAsUsed(owner, nonce);
- _increaseAllowance(owner, spender, increment);
- }
-
- /**
- * @notice Verify a signed authorization for a decrease in the allowance
- * granted to the spender and execute if valid
- * @param owner Token owner's address (Authorizer)
- * @param spender Spender's address
- * @param decrement Amount of decrease in allowance
- * @param validAfter The time after which this is valid (unix time)
- * @param validBefore The time before which this is valid (unix time)
- * @param nonce Unique nonce
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function _decreaseAllowanceWithAuthorization(
- address owner,
- address spender,
- uint256 decrement,
- uint256 validAfter,
- uint256 validBefore,
- bytes32 nonce,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) internal {
- _requireValidAuthorization(owner, nonce, validAfter, validBefore);
-
- bytes memory data = abi.encode(
- DECREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH,
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce
- );
- require(
- EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
- "FiatTokenV2: invalid signature"
- );
-
- _markAuthorizationAsUsed(owner, nonce);
- _decreaseAllowance(owner, spender, decrement);
- }
-
- /**
- * @notice Verify a signed approval authorization and execute if valid
- * @param owner Token owner's address (Authorizer)
- * @param spender Spender's address
- * @param value Amount of allowance
- * @param validAfter The time after which this is valid (unix time)
- * @param validBefore The time before which this is valid (unix time)
- * @param nonce Unique nonce
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function _approveWithAuthorization(
- address owner,
- address spender,
- uint256 value,
- uint256 validAfter,
- uint256 validBefore,
- bytes32 nonce,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) internal {
- _requireValidAuthorization(owner, nonce, validAfter, validBefore);
-
- bytes memory data = abi.encode(
- APPROVE_WITH_AUTHORIZATION_TYPEHASH,
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce
- );
- require(
- EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
- "FiatTokenV2: invalid signature"
- );
-
- _markAuthorizationAsUsed(owner, nonce);
- _approve(owner, spender, value);
- }
-
- /**
- * @notice Attempt to cancel an authorization
- * @param authorizer Authorizer's address
- * @param nonce Nonce of the authorization
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function _cancelAuthorization(
- address authorizer,
- bytes32 nonce,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) internal {
- _requireUnusedAuthorization(authorizer, nonce);
-
- bytes memory data = abi.encode(
- CANCEL_AUTHORIZATION_TYPEHASH,
- authorizer,
- nonce
- );
- require(
- EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == authorizer,
- "FiatTokenV2: invalid signature"
- );
-
- _authorizationStates[authorizer][nonce] = AuthorizationState.Canceled;
- emit AuthorizationCanceled(authorizer, nonce);
- }
-
- /**
- * @notice Check that an authorization is unused
- * @param authorizer Authorizer's address
- * @param nonce Nonce of the authorization
- */
- function _requireUnusedAuthorization(address authorizer, bytes32 nonce)
- private
- view
- {
- require(
- _authorizationStates[authorizer][nonce] ==
- AuthorizationState.Unused,
- "FiatTokenV2: authorization is used or canceled"
- );
- }
-
- /**
- * @notice Check that authorization is valid
- * @param authorizer Authorizer's address
- * @param nonce Nonce of the authorization
- * @param validAfter The time after which this is valid (unix time)
- * @param validBefore The time before which this is valid (unix time)
- */
- function _requireValidAuthorization(
- address authorizer,
- bytes32 nonce,
- uint256 validAfter,
- uint256 validBefore
- ) private view {
- require(
- now > validAfter,
- "FiatTokenV2: authorization is not yet valid"
- );
- require(now < validBefore, "FiatTokenV2: authorization is expired");
- _requireUnusedAuthorization(authorizer, nonce);
- }
-
- /**
- * @notice Mark an authorization as used
- * @param authorizer Authorizer's address
- * @param nonce Nonce of the authorization
- */
- function _markAuthorizationAsUsed(address authorizer, bytes32 nonce)
- private
- {
- _authorizationStates[authorizer][nonce] = AuthorizationState.Used;
- emit AuthorizationUsed(authorizer, nonce);
- }
-}
diff --git a/contracts/v2/Permit.sol b/contracts/v2/Permit.sol
deleted file mode 100644
index 47080a8a5..000000000
--- a/contracts/v2/Permit.sol
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * SPDX-License-Identifier: MIT
- *
- * Copyright (c) 2018-2020 CENTRE SECZ
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-pragma solidity 0.6.12;
-
-import { AbstractFiatTokenV2 } from "./AbstractFiatTokenV2.sol";
-import { EIP712Domain } from "./EIP712Domain.sol";
-import { EIP712 } from "../util/EIP712.sol";
-
-/**
- * @title Permit
- * @notice An alternative to approveWithAuthorization, provided for
- * compatibility with the draft EIP2612 proposed by Uniswap.
- * @dev Differences:
- * - Uses sequential nonce, which restricts transaction submission to one at a
- * time, or else it will revert
- * - Has deadline (= validBefore - 1) but does not have validAfter
- * - Doesn't have a way to change allowance atomically to prevent ERC20 multiple
- * withdrawal attacks
- */
-abstract contract Permit is AbstractFiatTokenV2, EIP712Domain {
- bytes32
- public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
- // = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
-
- mapping(address => uint256) private _permitNonces;
-
- /**
- * @notice Nonces for permit
- * @param owner Token owner's address (Authorizer)
- * @return Next nonce
- */
- function nonces(address owner) external view returns (uint256) {
- return _permitNonces[owner];
- }
-
- /**
- * @notice Verify a signed approval permit and execute if valid
- * @param owner Token owner's address (Authorizer)
- * @param spender Spender's address
- * @param value Amount of allowance
- * @param deadline The time at which this expires (unix time)
- * @param v v of the signature
- * @param r r of the signature
- * @param s s of the signature
- */
- function _permit(
- address owner,
- address spender,
- uint256 value,
- uint256 deadline,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) internal {
- require(deadline >= now, "FiatTokenV2: permit is expired");
-
- bytes memory data = abi.encode(
- PERMIT_TYPEHASH,
- owner,
- spender,
- value,
- _permitNonces[owner]++,
- deadline
- );
- require(
- EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) == owner,
- "FiatTokenV2: invalid signature"
- );
-
- _approve(owner, spender, value);
- }
-}
diff --git a/contracts/v2/celo/FiatTokenCeloV2_2.sol b/contracts/v2/celo/FiatTokenCeloV2_2.sol
new file mode 100644
index 000000000..f75e75311
--- /dev/null
+++ b/contracts/v2/celo/FiatTokenCeloV2_2.sol
@@ -0,0 +1,190 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
+import { FiatTokenV2_2 } from "../FiatTokenV2_2.sol";
+import { ICeloGasToken } from "../../interface/celo/ICeloGasToken.sol";
+
+contract FiatTokenCeloV2_2 is FiatTokenV2_2, ICeloGasToken {
+ using SafeMath for uint256;
+ event FeeCallerChanged(address indexed newAddress);
+
+ /**
+ * @notice Constant containing the storage slot indicating the current fee caller of
+ * `debitGasFees` and `creditGasFees`. Only the fee caller should be able to represent
+ * this FiatToken during a gas lifecycle. This slot starts off indicating address(0)
+ * as the allowed fee caller, as the storage slot is empty.
+ * @dev This constant is the Keccak-256 hash of "com.circle.fiattoken.celo.feecaller" and is
+ * validated in the contract constructor. It does not occupy any storage slots, since
+ * constants are embedded in the bytecode of a smart contract. This is intentionally done
+ * so that the Celo variant of FiatToken can accommodate new state variables that may be
+ * added in future FiatToken versions.
+ */
+ bytes32
+ private constant FEE_CALLER_SLOT = 0xdca914aef3e4e19727959ebb1e70b58822e2c7b796d303902adc19513fcb4af5;
+
+ /**
+ * @notice Returns the current fee caller address allowed on `debitGasFees` and `creditGasFees`.
+ * @dev Though Solidity generates implicit viewers/getters on contract state, because we
+ * store the fee caller in a custom Keccak256 slot instead of a standard declaration, we
+ * need an explicit getter for that slot.
+ */
+ function feeCaller() public view returns (address value) {
+ assembly {
+ value := sload(FEE_CALLER_SLOT)
+ }
+ }
+
+ modifier onlyFeeCaller() virtual {
+ require(
+ msg.sender == feeCaller(),
+ "FiatTokenCeloV2_2: caller is not the fee caller"
+ );
+ _;
+ }
+
+ /**
+ * @notice Updates the fee caller address.
+ * @param _newFeeCaller The address of the new pauser.
+ */
+ function updateFeeCaller(address _newFeeCaller) external onlyOwner {
+ assembly {
+ sstore(FEE_CALLER_SLOT, _newFeeCaller)
+ }
+ emit FeeCallerChanged(_newFeeCaller);
+ }
+
+ /**
+ * @notice Constant containing the storage slot indicating the debited value currently
+ * reserved for a transaction's gas paid in this token. This value also serves as a flag
+ * indicating whether a debit is ongoing. Before and after every unique transaction on
+ * the network, this slot should store a value of zero.
+ * @dev This constant is the Keccak-256 hash of "com.circle.fiattoken.celo.debit" and is
+ * validated in the contract constructor. It does not occupy any storage slots, since
+ * constants are embedded in the bytecode of a smart contract. This is intentionally done
+ * so that the Celo variant of FiatToken can accommodate new state variables that may be
+ * added in future FiatToken versions.
+ */
+ bytes32
+ private constant DEBITED_VALUE_SLOT = 0xd90dccaa76fe7208f2f477143b6adabfeb5d4a5136982894dfc51177fa8eda28;
+
+ function _debitedValue() internal view returns (uint256 value) {
+ assembly {
+ value := sload(DEBITED_VALUE_SLOT)
+ }
+ }
+
+ constructor() public {
+ assert(
+ DEBITED_VALUE_SLOT == keccak256("com.circle.fiattoken.celo.debit")
+ );
+ assert(
+ FEE_CALLER_SLOT == keccak256("com.circle.fiattoken.celo.feecaller")
+ );
+ }
+
+ function debitGasFees(address from, uint256 value)
+ external
+ override
+ onlyFeeCaller
+ whenNotPaused
+ notBlacklisted(from)
+ {
+ require(
+ _debitedValue() == 0,
+ "FiatTokenCeloV2_2: Must fully credit before debit"
+ );
+ require(from != address(0), "ERC20: transfer from the zero address");
+
+ _transferReservedGas(from, address(0), value);
+ assembly {
+ sstore(DEBITED_VALUE_SLOT, value)
+ }
+ }
+
+ function creditGasFees(
+ address from,
+ address feeRecipient,
+ // solhint-disable-next-line no-unused-vars
+ address gatewayFeeRecipient,
+ address communityFund,
+ uint256 refund,
+ uint256 tipTxFee,
+ // solhint-disable-next-line no-unused-vars
+ uint256 gatewayFee,
+ uint256 baseTxFee
+ )
+ external
+ override
+ onlyFeeCaller
+ whenNotPaused
+ notBlacklisted(from)
+ notBlacklisted(feeRecipient)
+ notBlacklisted(communityFund)
+ {
+ uint256 creditValue = refund.add(tipTxFee).add(baseTxFee);
+
+ // Because the Celo VM follows 1) debit, 2) main execution, and
+ // 3) credit atomically as part of a single on-chain transaction,
+ // we must ensure that the credit step attempts to credit pre-
+ // cisely what was debited prior.
+ require(
+ _debitedValue() == creditValue,
+ "FiatTokenCeloV2_2: Either no debit or mismatched debit"
+ );
+
+ // The credit portion of the gas lifecycle can be summarized
+ // by the three Transfer events emitted here:
+ // 0x0 to debitee,
+ _transferReservedGas(address(0), from, creditValue);
+ // debitee to validator,
+ _transfer(from, feeRecipient, tipTxFee);
+ // and debitee to Celo community fund.
+ _transfer(from, communityFund, baseTxFee);
+
+ // Mark the end of this debit-credit cycle.
+ assembly {
+ sstore(DEBITED_VALUE_SLOT, 0)
+ }
+ }
+
+ /**
+ * @dev This function differs from the standard _transfer function in that
+ * it does *not* check against the from and the to addresses being 0x0.
+ * This is needed for the usage of 0x0 as the gas intermediary.
+ * Further, this function validates that _value is > 0. For a comparison,
+ * see the FiatTokenV1#_transfer function.
+ */
+ function _transferReservedGas(
+ address _from,
+ address _to,
+ uint256 _value
+ ) internal {
+ require(_value > 0, "FiatTokenCeloV2_2: Must reserve > 0 gas");
+ require(
+ _value <= _balanceOf(_from),
+ "ERC20: transfer amount exceeds balance"
+ );
+
+ _setBalance(_from, _balanceOf(_from).sub(_value));
+ _setBalance(_to, _balanceOf(_to).add(_value));
+ emit Transfer(_from, _to, _value);
+ }
+}
diff --git a/contracts/v2/celo/FiatTokenFeeAdapterProxy.sol b/contracts/v2/celo/FiatTokenFeeAdapterProxy.sol
new file mode 100644
index 000000000..d005bec47
--- /dev/null
+++ b/contracts/v2/celo/FiatTokenFeeAdapterProxy.sol
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import {
+ AdminUpgradeabilityProxy
+} from "../../upgradeability/AdminUpgradeabilityProxy.sol";
+
+/**
+ * @title FiatTokenFeeAdapterProxy
+ * @dev This contract proxies FiatTokenFeeAdapter calls and enables FiatTokenFeeAdapter upgrades.
+ */
+contract FiatTokenFeeAdapterProxy is AdminUpgradeabilityProxy {
+ constructor(address implementationContract)
+ public
+ AdminUpgradeabilityProxy(implementationContract)
+ {}
+}
diff --git a/contracts/v2/celo/FiatTokenFeeAdapterV1.sol b/contracts/v2/celo/FiatTokenFeeAdapterV1.sol
new file mode 100644
index 000000000..f2b0b0499
--- /dev/null
+++ b/contracts/v2/celo/FiatTokenFeeAdapterV1.sol
@@ -0,0 +1,173 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import {
+ IFiatTokenFeeAdapter
+} from "../../interface/celo/IFiatTokenFeeAdapter.sol";
+import { ICeloGasToken } from "../../interface/celo/ICeloGasToken.sol";
+import { IDecimals } from "../../interface/celo/IDecimals.sol";
+import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
+
+contract FiatTokenFeeAdapterV1 is IFiatTokenFeeAdapter {
+ using SafeMath for uint256;
+
+ ICeloGasToken public adaptedToken;
+
+ uint8 internal _initializedVersion;
+ uint8 public adapterDecimals;
+ uint8 public tokenDecimals;
+ uint256 public upscaleFactor;
+ // This debited value matches the value stored on the
+ // underlying token and is calculated by downscaling.
+ uint256 internal _debitedValue = 0;
+
+ modifier onlyCeloVm() virtual {
+ require(
+ msg.sender == address(0),
+ "FiatTokenFeeAdapterV1: caller is not VM"
+ );
+ _;
+ }
+
+ function initializeV1(address _adaptedToken, uint8 _adapterDecimals)
+ public
+ virtual
+ {
+ // solhint-disable-next-line reason-string
+ require(_initializedVersion == 0);
+
+ tokenDecimals = IDecimals(_adaptedToken).decimals();
+ require(
+ tokenDecimals < _adapterDecimals,
+ "FiatTokenFeeAdapterV1: Token decimals must be < adapter decimals"
+ );
+ require(
+ // uint256 supports a max value of ~1.1579e77. Having the upscale
+ // factor be 1e78 would overflow, but SafeMath does not implement
+ // a `pow` function, so we must be careful here instead.
+ _adapterDecimals - tokenDecimals < 78,
+ "FiatTokenFeeAdapterV1: Digit difference too large"
+ );
+ upscaleFactor = uint256(10)**uint256(_adapterDecimals - tokenDecimals);
+
+ adapterDecimals = _adapterDecimals;
+ adaptedToken = ICeloGasToken(_adaptedToken);
+
+ _initializedVersion = 1;
+ }
+
+ function balanceOf(address account)
+ external
+ override
+ view
+ returns (uint256)
+ {
+ return _upscale(adaptedToken.balanceOf(account));
+ }
+
+ function debitGasFees(address from, uint256 value)
+ external
+ override
+ onlyCeloVm
+ {
+ require(
+ _debitedValue == 0,
+ "FiatTokenFeeAdapterV1: Must fully credit before debit"
+ );
+ uint256 valueScaled = _downscale(value);
+ adaptedToken.debitGasFees(from, valueScaled);
+ _debitedValue = valueScaled;
+ }
+
+ function creditGasFees(
+ address refundRecipient,
+ address feeRecipient,
+ // solhint-disable-next-line no-unused-vars
+ address gatewayFeeRecipient,
+ address communityFund,
+ uint256 refund,
+ uint256 tipTxFee,
+ // solhint-disable-next-line no-unused-vars
+ uint256 gatewayFee,
+ uint256 baseTxFee
+ ) external override onlyCeloVm {
+ if (_debitedValue == 0) {
+ // When eth.estimateGas is called, this function is
+ // called, but we don't want to credit anything, as
+ // the edge case also violates the invariant. See
+ // https://github.com/celo-org/celo-blockchain/blob/6388f0ec88fb7a2a82ee41b0e2c9cb7e2cff87e2/internal/ethapi/api.go#L1018-L1022.
+ return;
+ }
+
+ uint256 refundScaled = _downscale(refund);
+ uint256 tipTxFeeScaled = _downscale(tipTxFee);
+ uint256 baseTxFeeScaled = _downscale(baseTxFee);
+ uint256 creditValueScaled = refundScaled.add(tipTxFeeScaled).add(
+ baseTxFeeScaled
+ );
+
+ require(
+ creditValueScaled <= _debitedValue,
+ "FiatTokenFeeAdapterV1: Cannot credit more than debited"
+ );
+
+ // When downscaling, data can be lost, leading to inaccurate sums.
+ uint256 roundingError = _debitedValue.sub(creditValueScaled);
+ if (roundingError > 0) {
+ // In this case, allocate the remainder to the community fund (base fee).
+ // Instead of allocating to the validator (tipTxFee), we do this to prevent
+ // the risk of actors gaming the scaling system (even if the actual difference
+ // is expected to be very small).
+ baseTxFeeScaled = baseTxFeeScaled.add(roundingError);
+ }
+
+ adaptedToken.creditGasFees(
+ refundRecipient,
+ feeRecipient,
+ address(0),
+ communityFund,
+ refundScaled,
+ tipTxFeeScaled,
+ 0,
+ baseTxFeeScaled
+ );
+
+ _debitedValue = 0;
+ }
+
+ /**
+ * @notice Upscales a given value to logically have the same number of decimals as this adapter.
+ * @param value The value to upscale.
+ * @dev The caller is responsible for preconditions, as uint256 does not provide decimals.
+ */
+ function _upscale(uint256 value) internal view returns (uint256) {
+ return value.mul(upscaleFactor);
+ }
+
+ /**
+ * @notice Downscales a given value consistent with this adapter to its original factor.
+ * @param value The value to downscale.
+ * @dev The caller is responsible for preconditions, as uint256 does not provide decimals.
+ * This downscaling will round down on the division operator.
+ */
+ function _downscale(uint256 value) internal view returns (uint256) {
+ return value.div(upscaleFactor);
+ }
+}
diff --git a/contracts/v2/upgrader/AbstractV2Upgrader.sol b/contracts/v2/upgrader/AbstractV2Upgrader.sol
new file mode 100644
index 000000000..e9604ca90
--- /dev/null
+++ b/contracts/v2/upgrader/AbstractV2Upgrader.sol
@@ -0,0 +1,120 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+import { Ownable } from "../../v1/Ownable.sol";
+import { FiatTokenProxy } from "../../v1/FiatTokenProxy.sol";
+import { AbstractUpgraderHelper } from "./helpers/AbstractUpgraderHelper.sol";
+
+/**
+ * @dev An abstract contract to encapsulate any common logic
+ * for any V2+ Upgrader contracts.
+ */
+abstract contract AbstractV2Upgrader is Ownable {
+ using SafeMath for uint256;
+
+ FiatTokenProxy internal _proxy;
+ address internal _implementation;
+ address internal _newProxyAdmin;
+ AbstractUpgraderHelper internal _helper;
+
+ /**
+ * @notice Constructor
+ * @param proxy FiatTokenProxy contract
+ * @param implementation Address of the implementation contract
+ * @param newProxyAdmin Grantee of proxy admin role after upgrade
+ */
+ constructor(
+ FiatTokenProxy proxy,
+ address implementation,
+ address newProxyAdmin
+ ) public Ownable() {
+ _proxy = proxy;
+ _implementation = implementation;
+ _newProxyAdmin = newProxyAdmin;
+ }
+
+ /**
+ * @notice The address of the FiatTokenProxy contract
+ * @return Contract address
+ */
+ function proxy() external view returns (address) {
+ return address(_proxy);
+ }
+
+ /**
+ * @notice The address of the FiatTokenV2 implementation contract
+ * @return Contract address
+ */
+ function implementation() external view returns (address) {
+ return _implementation;
+ }
+
+ /**
+ * @notice The address of the V2UpgraderHelper contract
+ * @return Contract address
+ */
+ function helper() external view returns (address) {
+ return address(_helper);
+ }
+
+ /**
+ * @notice The address to which the proxy admin role will be transferred
+ * after the upgrade is completed
+ * @return Address
+ */
+ function newProxyAdmin() external view returns (address) {
+ return _newProxyAdmin;
+ }
+
+ /**
+ * @notice Withdraw any FiatToken in the contract
+ */
+ function withdrawFiatToken() public onlyOwner {
+ IERC20 fiatToken = IERC20(address(_proxy));
+ uint256 balance = fiatToken.balanceOf(address(this));
+ if (balance > 0) {
+ require(
+ fiatToken.transfer(msg.sender, balance),
+ "Failed to withdraw FiatToken"
+ );
+ }
+ }
+
+ /**
+ * @notice Transfer proxy admin role to newProxyAdmin, and self-destruct
+ */
+ function abortUpgrade() external onlyOwner {
+ // Transfer proxy admin role
+ _proxy.changeAdmin(_newProxyAdmin);
+
+ // Tear down
+ tearDown();
+ }
+
+ /**
+ * @dev Tears down the helper contract followed by this contract.
+ */
+ function tearDown() internal {
+ _helper.tearDown();
+ selfdestruct(msg.sender);
+ }
+}
diff --git a/contracts/v2/upgrader/V2Upgrader.sol b/contracts/v2/upgrader/V2Upgrader.sol
index bc1cd8835..a2c17d085 100644
--- a/contracts/v2/upgrader/V2Upgrader.sol
+++ b/contracts/v2/upgrader/V2Upgrader.sol
@@ -1,107 +1,59 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import { Ownable } from "../../v1/Ownable.sol";
import { FiatTokenV2 } from "../FiatTokenV2.sol";
import { FiatTokenProxy } from "../../v1/FiatTokenProxy.sol";
-import { V2UpgraderHelper } from "./V2UpgraderHelper.sol";
+import { V2UpgraderHelper } from "./helpers/V2UpgraderHelper.sol";
+import { AbstractV2Upgrader } from "./AbstractV2Upgrader.sol";
/**
* @title V2 Upgrader
- * @notice Performs USDC v2 upgrade, and runs a basic sanity test in a single
- * atomic transaction, rolling back if any issues are found. This may be
- * overkill, but the peace of mind is worth the gas spent. By performing the
+ * @notice Performs FiatToken v2 upgrade, and runs a basic sanity test in a single
+ * atomic transaction, rolling back if any issues are found. By performing the
* upgrade atomically, it ensures that there is no disruption of service if the
* upgrade is not successful for some unforeseen circumstances.
- * @dev Read docs/v2_upgrade.md
+ * @dev Read doc/v2_upgrade.md
*/
-contract V2Upgrader is Ownable {
+contract V2Upgrader is AbstractV2Upgrader {
using SafeMath for uint256;
- FiatTokenProxy private _proxy;
- FiatTokenV2 private _implementation;
- address private _newProxyAdmin;
string private _newName;
- V2UpgraderHelper private _helper;
/**
* @notice Constructor
* @param proxy FiatTokenProxy contract
* @param implementation FiatTokenV2 implementation contract
* @param newProxyAdmin Grantee of proxy admin role after upgrade
- * @param newName New ERC20 name (e.g. "USD//C" -> "USD Coin")
+ * @param newName New ERC20 name (e.g. "USD//C" -> "USDC")
*/
constructor(
FiatTokenProxy proxy,
FiatTokenV2 implementation,
address newProxyAdmin,
string memory newName
- ) public Ownable() {
- _proxy = proxy;
- _implementation = implementation;
- _newProxyAdmin = newProxyAdmin;
+ ) public AbstractV2Upgrader(proxy, address(implementation), newProxyAdmin) {
_newName = newName;
_helper = new V2UpgraderHelper(address(proxy));
}
- /**
- * @notice The address of the FiatTokenProxy contract
- * @return Contract address
- */
- function proxy() external view returns (address) {
- return address(_proxy);
- }
-
- /**
- * @notice The address of the FiatTokenV2 implementation contract
- * @return Contract address
- */
- function implementation() external view returns (address) {
- return address(_implementation);
- }
-
- /**
- * @notice The address of the V2UpgraderHelper contract
- * @return Contract address
- */
- function helper() external view returns (address) {
- return address(_helper);
- }
-
- /**
- * @notice The address to which the proxy admin role will be transferred
- * after the upgrade is completed
- * @return Address
- */
- function newProxyAdmin() external view returns (address) {
- return _newProxyAdmin;
- }
-
/**
* @notice New ERC20 token name
* @return New Name
@@ -119,24 +71,25 @@ contract V2Upgrader is Ownable {
// The helper needs to be used to read contract state because
// AdminUpgradeabilityProxy does not allow the proxy admin to make
// proxy calls.
+ V2UpgraderHelper v2Helper = V2UpgraderHelper(address(_helper));
// Check that this contract sufficient funds to run the tests
- uint256 contractBal = _helper.balanceOf(address(this));
- require(contractBal >= 2e5, "V2Upgrader: 0.2 USDC needed");
+ uint256 contractBal = v2Helper.balanceOf(address(this));
+ require(contractBal >= 2e5, "V2Upgrader: 0.2 FiatToken needed");
- uint256 callerBal = _helper.balanceOf(msg.sender);
+ uint256 callerBal = v2Helper.balanceOf(msg.sender);
// Keep original contract metadata
- string memory symbol = _helper.symbol();
- uint8 decimals = _helper.decimals();
- string memory currency = _helper.currency();
- address masterMinter = _helper.masterMinter();
- address owner = _helper.fiatTokenOwner();
- address pauser = _helper.pauser();
- address blacklister = _helper.blacklister();
+ string memory symbol = v2Helper.symbol();
+ uint8 decimals = v2Helper.decimals();
+ string memory currency = v2Helper.currency();
+ address masterMinter = v2Helper.masterMinter();
+ address owner = v2Helper.fiatTokenOwner();
+ address pauser = v2Helper.pauser();
+ address blacklister = v2Helper.blacklister();
// Change implementation contract address
- _proxy.upgradeTo(address(_implementation));
+ _proxy.upgradeTo(_implementation);
// Transfer proxy admin role
_proxy.changeAdmin(_newProxyAdmin);
@@ -175,46 +128,19 @@ contract V2Upgrader is Ownable {
// Test approve/transferFrom
require(
- v2.approve(address(_helper), 1e5) &&
- v2.allowance(address(this), address(_helper)) == 1e5 &&
- _helper.transferFrom(address(this), msg.sender, 1e5) &&
+ v2.approve(address(v2Helper), 1e5) &&
+ v2.allowance(address(this), address(v2Helper)) == 1e5 &&
+ v2Helper.transferFrom(address(this), msg.sender, 1e5) &&
v2.allowance(address(this), msg.sender) == 0 &&
v2.balanceOf(msg.sender) == callerBal.add(2e5) &&
v2.balanceOf(address(this)) == contractBal.sub(2e5),
"V2Upgrader: approve/transferFrom test failed"
);
- // Transfer any remaining USDC to the caller
- withdrawUSDC();
-
- // Tear down
- _helper.tearDown();
- selfdestruct(msg.sender);
- }
-
- /**
- * @notice Withdraw any USDC in the contract
- */
- function withdrawUSDC() public onlyOwner {
- IERC20 usdc = IERC20(address(_proxy));
- uint256 balance = usdc.balanceOf(address(this));
- if (balance > 0) {
- require(
- usdc.transfer(msg.sender, balance),
- "V2Upgrader: failed to withdraw USDC"
- );
- }
- }
-
- /**
- * @notice Transfer proxy admin role to newProxyAdmin, and self-destruct
- */
- function abortUpgrade() external onlyOwner {
- // Transfer proxy admin role
- _proxy.changeAdmin(_newProxyAdmin);
+ // Transfer any remaining FiatToken to the caller
+ withdrawFiatToken();
// Tear down
- _helper.tearDown();
- selfdestruct(msg.sender);
+ tearDown();
}
}
diff --git a/contracts/v2/upgrader/V2_1Upgrader.sol b/contracts/v2/upgrader/V2_1Upgrader.sol
new file mode 100644
index 000000000..bde70daf9
--- /dev/null
+++ b/contracts/v2/upgrader/V2_1Upgrader.sol
@@ -0,0 +1,149 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
+import { FiatTokenV2_1 } from "../FiatTokenV2_1.sol";
+import { FiatTokenProxy } from "../../v1/FiatTokenProxy.sol";
+import { V2UpgraderHelper } from "./helpers/V2UpgraderHelper.sol";
+import { AbstractV2Upgrader } from "./AbstractV2Upgrader.sol";
+
+/**
+ * @title V2.1 Upgrader
+ * @notice Performs FiatToken v2.1 upgrade, and runs a basic sanity test in a single
+ * atomic transaction, rolling back if any issues are found. By performing the
+ * upgrade atomically, it ensures that there is no disruption of service if the
+ * upgrade is not successful for some unforeseen circumstances.
+ * @dev Read doc/v2.1_upgrade.md
+ */
+contract V2_1Upgrader is AbstractV2Upgrader {
+ using SafeMath for uint256;
+
+ address private _lostAndFound;
+
+ /**
+ * @notice Constructor
+ * @param proxy FiatTokenProxy contract
+ * @param implementation FiatTokenV2_1 implementation contract
+ * @param newProxyAdmin Grantee of proxy admin role after upgrade
+ * @param lostAndFound The address to which the locked funds are sent
+ */
+ constructor(
+ FiatTokenProxy proxy,
+ FiatTokenV2_1 implementation,
+ address newProxyAdmin,
+ address lostAndFound
+ ) public AbstractV2Upgrader(proxy, address(implementation), newProxyAdmin) {
+ _lostAndFound = lostAndFound;
+ _helper = new V2UpgraderHelper(address(proxy));
+ }
+
+ /**
+ * @notice The address to which the locked funds will be sent as part of the
+ * initialization process
+ * @return Address
+ */
+ function lostAndFound() external view returns (address) {
+ return _lostAndFound;
+ }
+
+ /**
+ * @notice Upgrade, transfer proxy admin role to a given address, run a
+ * sanity test, and tear down the upgrader contract, in a single atomic
+ * transaction. It rolls back if there is an error.
+ */
+ function upgrade() external onlyOwner {
+ // The helper needs to be used to read contract state because
+ // AdminUpgradeabilityProxy does not allow the proxy admin to make
+ // proxy calls.
+ V2UpgraderHelper v2_1Helper = V2UpgraderHelper(address(_helper));
+
+ // Check that this contract sufficient funds to run the tests
+ uint256 contractBal = v2_1Helper.balanceOf(address(this));
+ require(contractBal >= 2e5, "V2_1Upgrader: 0.2 FiatToken needed");
+
+ uint256 callerBal = v2_1Helper.balanceOf(msg.sender);
+
+ // Keep original contract metadata
+ string memory name = v2_1Helper.name();
+ string memory symbol = v2_1Helper.symbol();
+ uint8 decimals = v2_1Helper.decimals();
+ string memory currency = v2_1Helper.currency();
+ address masterMinter = v2_1Helper.masterMinter();
+ address owner = v2_1Helper.fiatTokenOwner();
+ address pauser = v2_1Helper.pauser();
+ address blacklister = v2_1Helper.blacklister();
+
+ // Change implementation contract address
+ _proxy.upgradeTo(_implementation);
+
+ // Transfer proxy admin role
+ _proxy.changeAdmin(_newProxyAdmin);
+
+ // Initialize V2 contract
+ FiatTokenV2_1 v2_1 = FiatTokenV2_1(address(_proxy));
+ v2_1.initializeV2_1(_lostAndFound);
+
+ // Sanity test
+ // Check metadata
+ require(
+ keccak256(bytes(name)) == keccak256(bytes(v2_1.name())) &&
+ keccak256(bytes(symbol)) == keccak256(bytes(v2_1.symbol())) &&
+ decimals == v2_1.decimals() &&
+ keccak256(bytes(currency)) ==
+ keccak256(bytes(v2_1.currency())) &&
+ masterMinter == v2_1.masterMinter() &&
+ owner == v2_1.owner() &&
+ pauser == v2_1.pauser() &&
+ blacklister == v2_1.blacklister(),
+ "V2_1Upgrader: metadata test failed"
+ );
+
+ // Test balanceOf
+ require(
+ v2_1.balanceOf(address(this)) == contractBal,
+ "V2_1Upgrader: balanceOf test failed"
+ );
+
+ // Test transfer
+ require(
+ v2_1.transfer(msg.sender, 1e5) &&
+ v2_1.balanceOf(msg.sender) == callerBal.add(1e5) &&
+ v2_1.balanceOf(address(this)) == contractBal.sub(1e5),
+ "V2_1Upgrader: transfer test failed"
+ );
+
+ // Test approve/transferFrom
+ require(
+ v2_1.approve(address(v2_1Helper), 1e5) &&
+ v2_1.allowance(address(this), address(v2_1Helper)) == 1e5 &&
+ v2_1Helper.transferFrom(address(this), msg.sender, 1e5) &&
+ v2_1.allowance(address(this), msg.sender) == 0 &&
+ v2_1.balanceOf(msg.sender) == callerBal.add(2e5) &&
+ v2_1.balanceOf(address(this)) == contractBal.sub(2e5),
+ "V2_1Upgrader: approve/transferFrom test failed"
+ );
+
+ // Transfer any remaining FiatToken to the caller
+ withdrawFiatToken();
+
+ // Tear down
+ tearDown();
+ }
+}
diff --git a/contracts/v2/upgrader/V2_2Upgrader.sol b/contracts/v2/upgrader/V2_2Upgrader.sol
new file mode 100644
index 000000000..baef20bba
--- /dev/null
+++ b/contracts/v2/upgrader/V2_2Upgrader.sol
@@ -0,0 +1,208 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
+import { FiatTokenV2_2 } from "../FiatTokenV2_2.sol";
+import { FiatTokenProxy } from "../../v1/FiatTokenProxy.sol";
+import { V2_2UpgraderHelper } from "./helpers/V2_2UpgraderHelper.sol";
+import { AbstractV2Upgrader } from "./AbstractV2Upgrader.sol";
+
+/**
+ * @title V2.2 Upgrader
+ * @notice Performs FiatToken v2.2 upgrade, and runs a basic sanity test in a single
+ * atomic transaction, rolling back if any issues are found. By performing the
+ * upgrade atomically, it ensures that there is no disruption of service if the
+ * upgrade is not successful for some unforeseen circumstances.
+ * @dev Read doc/v2.2_upgrade.md
+ */
+contract V2_2Upgrader is AbstractV2Upgrader {
+ using SafeMath for uint256;
+
+ struct FiatTokenMetadata {
+ string name;
+ uint8 decimals;
+ string currency;
+ string version;
+ bytes32 domainSeparator;
+ address masterMinter;
+ address owner;
+ address pauser;
+ address blacklister;
+ address rescuer;
+ bool paused;
+ uint256 totalSupply;
+ }
+
+ address[] private _accountsToBlacklist;
+ string private _newSymbol;
+
+ /**
+ * @notice Constructor
+ * @param proxy FiatTokenProxy contract
+ * @param implementation FiatTokenV2_2 implementation contract
+ * @param newProxyAdmin Grantee of proxy admin role after upgrade
+ * @param accountsToBlacklist Accounts to add to the new blacklist data structure
+ * @param newSymbol New token symbol
+ */
+ constructor(
+ FiatTokenProxy proxy,
+ FiatTokenV2_2 implementation,
+ address newProxyAdmin,
+ address[] memory accountsToBlacklist,
+ string memory newSymbol
+ ) public AbstractV2Upgrader(proxy, address(implementation), newProxyAdmin) {
+ _helper = new V2_2UpgraderHelper(address(proxy));
+ _accountsToBlacklist = accountsToBlacklist;
+ _newSymbol = newSymbol;
+ }
+
+ /**
+ * @notice The list of blacklisted accounts to migrate to the blacklist data structure.
+ * @return Address[] the list of accounts to blacklist.
+ */
+ function accountsToBlacklist() external view returns (address[] memory) {
+ return _accountsToBlacklist;
+ }
+
+ /**
+ * @notice Upgrade, transfer proxy admin role to a given address, run a
+ * sanity test, and tear down the upgrader contract, in a single atomic
+ * transaction. It rolls back if there is an error.
+ */
+ function upgrade() external onlyOwner {
+ // The helper needs to be used to read contract state because
+ // AdminUpgradeabilityProxy does not allow the proxy admin to make
+ // proxy calls.
+ V2_2UpgraderHelper v2_2Helper = V2_2UpgraderHelper(address(_helper));
+
+ // Check that this contract sufficient funds to run the tests
+ uint256 contractBal = v2_2Helper.balanceOf(address(this));
+ require(contractBal >= 2e5, "V2_2Upgrader: 0.2 FiatToken needed");
+
+ uint256 callerBal = v2_2Helper.balanceOf(msg.sender);
+
+ // Keep original contract metadata
+ FiatTokenMetadata memory originalMetadata = FiatTokenMetadata(
+ v2_2Helper.name(),
+ v2_2Helper.decimals(),
+ v2_2Helper.currency(),
+ v2_2Helper.version(),
+ v2_2Helper.DOMAIN_SEPARATOR(),
+ v2_2Helper.masterMinter(),
+ v2_2Helper.fiatTokenOwner(),
+ v2_2Helper.pauser(),
+ v2_2Helper.blacklister(),
+ v2_2Helper.rescuer(),
+ v2_2Helper.paused(),
+ v2_2Helper.totalSupply()
+ );
+
+ // Change implementation contract address
+ _proxy.upgradeTo(_implementation);
+
+ // Transfer proxy admin role
+ _proxy.changeAdmin(_newProxyAdmin);
+
+ // Initialize V2 contract
+ FiatTokenV2_2 v2_2 = FiatTokenV2_2(address(_proxy));
+ v2_2.initializeV2_2(_accountsToBlacklist, _newSymbol);
+
+ // Sanity test
+ // Check metadata
+ FiatTokenMetadata memory upgradedMetadata = FiatTokenMetadata(
+ v2_2.name(),
+ v2_2.decimals(),
+ v2_2.currency(),
+ v2_2.version(),
+ v2_2.DOMAIN_SEPARATOR(),
+ v2_2.masterMinter(),
+ v2_2.owner(),
+ v2_2.pauser(),
+ v2_2.blacklister(),
+ v2_2.rescuer(),
+ v2_2.paused(),
+ v2_2.totalSupply()
+ );
+ require(
+ checkFiatTokenMetadataEqual(originalMetadata, upgradedMetadata),
+ "V2_2Upgrader: metadata test failed"
+ );
+
+ // Check symbol is updated
+ require(
+ keccak256(bytes(v2_2.symbol())) == keccak256(bytes(_newSymbol)),
+ "V2_2Upgrader: symbol not updated"
+ );
+
+ // Test balanceOf
+ require(
+ v2_2.balanceOf(address(this)) == contractBal,
+ "V2_2Upgrader: balanceOf test failed"
+ );
+
+ // Test transfer
+ require(
+ v2_2.transfer(msg.sender, 1e5) &&
+ v2_2.balanceOf(msg.sender) == callerBal.add(1e5) &&
+ v2_2.balanceOf(address(this)) == contractBal.sub(1e5),
+ "V2_2Upgrader: transfer test failed"
+ );
+
+ // Test approve/transferFrom
+ require(
+ v2_2.approve(address(v2_2Helper), 1e5) &&
+ v2_2.allowance(address(this), address(v2_2Helper)) == 1e5 &&
+ v2_2Helper.transferFrom(address(this), msg.sender, 1e5) &&
+ v2_2.allowance(address(this), msg.sender) == 0 &&
+ v2_2.balanceOf(msg.sender) == callerBal.add(2e5) &&
+ v2_2.balanceOf(address(this)) == contractBal.sub(2e5),
+ "V2_2Upgrader: approve/transferFrom test failed"
+ );
+
+ // Transfer any remaining FiatToken to the caller
+ withdrawFiatToken();
+
+ // Tear down
+ tearDown();
+ }
+
+ /**
+ * @dev Checks whether two FiatTokenMetadata are equal.
+ * @return true if the two metadata are equal, false otherwise.
+ */
+ function checkFiatTokenMetadataEqual(
+ FiatTokenMetadata memory a,
+ FiatTokenMetadata memory b
+ ) private pure returns (bool) {
+ return
+ keccak256(bytes(a.name)) == keccak256(bytes(b.name)) &&
+ a.decimals == b.decimals &&
+ keccak256(bytes(a.currency)) == keccak256(bytes(b.currency)) &&
+ keccak256(bytes(a.version)) == keccak256(bytes(b.version)) &&
+ a.domainSeparator == b.domainSeparator &&
+ a.masterMinter == b.masterMinter &&
+ a.owner == b.owner &&
+ a.pauser == b.pauser &&
+ a.blacklister == b.blacklister &&
+ a.rescuer == b.rescuer &&
+ a.paused == b.paused &&
+ a.totalSupply == b.totalSupply;
+ }
+}
diff --git a/contracts/v2/upgrader/helpers/AbstractUpgraderHelper.sol b/contracts/v2/upgrader/helpers/AbstractUpgraderHelper.sol
new file mode 100644
index 000000000..0fc0b1cd9
--- /dev/null
+++ b/contracts/v2/upgrader/helpers/AbstractUpgraderHelper.sol
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pragma solidity 0.6.12;
+
+import { Ownable } from "../../../v1/Ownable.sol";
+
+/**
+ * @dev An abstract contract to encapsulate any common logic for any V2+ Upgrader Helper contracts.
+ * The helper enables the upgrader to read some contract state before it renounces the
+ * proxy admin role (Proxy admins cannot call delegated methods).
+ */
+abstract contract AbstractUpgraderHelper is Ownable {
+ address internal _proxy;
+
+ /**
+ * @notice Constructor
+ * @param fiatTokenProxy Address of the FiatTokenProxy contract
+ */
+ constructor(address fiatTokenProxy) public Ownable() {
+ _proxy = fiatTokenProxy;
+ }
+
+ /**
+ * @notice The address of the FiatTokenProxy contract
+ * @return Contract address
+ */
+ function proxy() external view returns (address) {
+ return _proxy;
+ }
+
+ /**
+ * @notice Tear down the contract (self-destruct)
+ */
+ function tearDown() external onlyOwner {
+ selfdestruct(msg.sender);
+ }
+}
diff --git a/contracts/v2/upgrader/V2UpgraderHelper.sol b/contracts/v2/upgrader/helpers/V2UpgraderHelper.sol
similarity index 59%
rename from contracts/v2/upgrader/V2UpgraderHelper.sol
rename to contracts/v2/upgrader/helpers/V2UpgraderHelper.sol
index dc0ed006c..88b00687f 100644
--- a/contracts/v2/upgrader/V2UpgraderHelper.sol
+++ b/contracts/v2/upgrader/helpers/V2UpgraderHelper.sol
@@ -1,56 +1,41 @@
/**
- * SPDX-License-Identifier: MIT
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
*
- * Copyright (c) 2018-2020 CENTRE SECZ
+ * SPDX-License-Identifier: Apache-2.0
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The above copyright notice and this permission notice shall be included in
- * copies or substantial portions of the Software.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
pragma solidity 0.6.12;
-import { FiatTokenV1 } from "../../v1/FiatTokenV1.sol";
-import { Ownable } from "../../v1/Ownable.sol";
+import { FiatTokenV1 } from "../../../v1/FiatTokenV1.sol";
+import { AbstractUpgraderHelper } from "./AbstractUpgraderHelper.sol";
/**
* @title V2 Upgrader Helper
* @dev Enables V2Upgrader to read some contract state before it renounces the
- * proxy admin role. (Proxy admins cannot call delegated methods.) It is also
+ * proxy admin role. (Proxy admins cannot call delegated methods). It is also
* used to test approve/transferFrom.
*/
-contract V2UpgraderHelper is Ownable {
- address private _proxy;
-
+contract V2UpgraderHelper is AbstractUpgraderHelper {
/**
* @notice Constructor
* @param fiatTokenProxy Address of the FiatTokenProxy contract
*/
- constructor(address fiatTokenProxy) public Ownable() {
- _proxy = fiatTokenProxy;
- }
-
- /**
- * @notice The address of the FiatTokenProxy contract
- * @return Contract address
- */
- function proxy() external view returns (address) {
- return address(_proxy);
- }
+ constructor(address fiatTokenProxy)
+ public
+ AbstractUpgraderHelper(fiatTokenProxy)
+ {}
/**
* @notice Call name()
@@ -140,11 +125,4 @@ contract V2UpgraderHelper is Ownable {
) external returns (bool) {
return FiatTokenV1(_proxy).transferFrom(from, to, value);
}
-
- /**
- * @notice Tear down the contract (self-destruct)
- */
- function tearDown() external onlyOwner {
- selfdestruct(msg.sender);
- }
}
diff --git a/contracts/v2/upgrader/helpers/V2_2UpgraderHelper.sol b/contracts/v2/upgrader/helpers/V2_2UpgraderHelper.sol
new file mode 100644
index 000000000..6dd1dac4b
--- /dev/null
+++ b/contracts/v2/upgrader/helpers/V2_2UpgraderHelper.sol
@@ -0,0 +1,80 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenV2_1 } from "../../../v2/FiatTokenV2_1.sol";
+import { V2UpgraderHelper } from "./V2UpgraderHelper.sol";
+
+/**
+ * @title V2.2 Upgrader Helper
+ * @dev Enables V2_2Upgrader to read some contract state before it renounces the
+ * proxy admin role. (Proxy admins cannot call delegated methods). It is also
+ * used to test approve/transferFrom.
+ */
+contract V2_2UpgraderHelper is V2UpgraderHelper {
+ /**
+ * @notice Constructor
+ * @param fiatTokenProxy Address of the FiatTokenProxy contract
+ */
+ constructor(address fiatTokenProxy)
+ public
+ V2UpgraderHelper(fiatTokenProxy)
+ {}
+
+ /**
+ * @notice Call version()
+ * @return version
+ */
+ function version() external view returns (string memory) {
+ return FiatTokenV2_1(_proxy).version();
+ }
+
+ /**
+ * @notice Call DOMAIN_SEPARATOR()
+ * @return domainSeparator
+ */
+ // solhint-disable-next-line func-name-mixedcase
+ function DOMAIN_SEPARATOR() external view returns (bytes32) {
+ return FiatTokenV2_1(_proxy).DOMAIN_SEPARATOR();
+ }
+
+ /**
+ * @notice Call rescuer()
+ * @return rescuer
+ */
+ function rescuer() external view returns (address) {
+ return FiatTokenV2_1(_proxy).rescuer();
+ }
+
+ /**
+ * @notice Call paused()
+ * @return paused
+ */
+ function paused() external view returns (bool) {
+ return FiatTokenV2_1(_proxy).paused();
+ }
+
+ /**
+ * @notice Call totalSupply()
+ * @return totalSupply
+ */
+ function totalSupply() external view returns (uint256) {
+ return FiatTokenV2_1(_proxy).totalSupply();
+ }
+}
diff --git a/doc/bridged_USDC_standard.md b/doc/bridged_USDC_standard.md
new file mode 100644
index 000000000..710fde6cd
--- /dev/null
+++ b/doc/bridged_USDC_standard.md
@@ -0,0 +1,269 @@
+# Bridged USDC Standard
+
+[Bridged USDC Standard](https://circle.com/blog/bridged-usdc-standard) is a
+specification and process for deploying a bridged form of USDC on EVM
+blockchains with optionality for Circle to seamlessly upgrade to native issuance
+in the future.1
+
+The result is a secure and standardized way for any EVM blockchain and rollup
+team to transfer ownership of a bridged USDC token contract to Circle to
+facilitate an upgrade to native USDC, if and when both parties deem
+appropriate.2
+
+This document provides a high-level overview of the process. Note that this also
+applies to implementations of bridged EURC (Circle’s euro-backed stablecoin), as
+they follow the same implementation.
+
+## How it works
+
+1. Third-party team follows the standard to deploy their bridge contracts, or
+ retains the ability to upgrade their bridge contracts in the future to
+ incorporate the required functionality. (See
+ [Bridge Contracts](#bridge-contracts))
+2. Third-party team follows the standard to deploy their bridged USDC token
+ contract. (See [Token Deployment](#token-deployment))
+3. If and when a joint decision is made by the third-party team and Circle to
+ securely transfer ownership of the bridged USDC token contract to Circle and
+ perform an upgrade to native USDC, the following will take place:
+ - Third-party team will pause bridging activity and reconcile in-flight
+ bridging activity to finalize the total supply of bridged USDC on the
+ destination chain.
+ - Third-party team will securely re-assign the contract roles of the bridged
+ USDC token contract to Circle.
+ - Circle and the third-party team will jointly coordinate to burn an amount
+ of native USDC locked in the bridge contract on the origin chain that
+ equals the supply of bridged USDC on the destination chain and upgrade the
+ bridged USDC token contract on the destination chain to native USDC.
+4. The native USDC token contract seamlessly retains the existing supply,
+ holders, and app integrations of the original bridged USDC token contract.
+
+## Bridge Contracts
+
+The third-party team’s bridge contracts play an integral role in the process,
+and must be upgradable in order to add the following functionality, which is
+required to support the upgrade process.
+
+1. (_Source and destination blockchains_) Ability to pause USDC bridging to
+ create a lock on the supply.
+2. (_Source blockchain_) Ability to burn locked USDC.
+
+Circle recommends deferring adding this functionality to a later time through a
+contract upgrade after Circle and the third-party team have jointly agreed to
+proceed with an upgrade.
+
+### 1) Ability to pause USDC bridging
+
+The bridge contracts must be able to pause bridging, enabling a finalization of
+the supply of the bridged token with that supply being fully backed by an amount
+of native USDC on the source chain. How this is implemented is up to the
+third-party team, but this functionality must be present before an upgrade can
+take place.
+
+### 2) Ability to burn locked USDC
+
+A final step during the upgrade is to burn locked USDC in the source blockchain
+bridge contract. To support this, Circle will temporarily assign the bridge
+contract holding the USDC balance the role of a zero-allowance USDC minter. This
+means that the bridge may burn its own held balance but not mint new supply.
+
+To execute the burn, the bridge contract must expose a single function, only
+callable by a Circle-controlled account. The signature of this function will be:
+
+```
+function burnLockedUSDC() external;
+```
+
+The specific implementation details are left up to the third-party team, but at
+a minimum, the function must:
+
+1. Be only callable by an address that Circle specifies closer to the time of
+ the upgrade. Note that this address will not necessarily be the same address
+ that is specified to call `transferUSDCRoles`.
+2. Burn an amount of USDC held by the bridge that equals the total supply of
+ bridged USDC finalized by the supply lock.
+
+## Token Deployment
+
+The third-party team’s bridged USDC token contract is expected to be identical
+to native USDC token contracts on other EVM blockchains. USDC uses a proxy
+pattern, so the standard applies to both the implementation contract code and
+the token proxy.
+
+### Token Contract Code
+
+Using identical code facilitates trustless contract verification by Circle and
+supports a seamless integration with existing USDC services. To facilitate this,
+the third-party team should:
+
+1. Build the [FiatToken contracts](../README.md#contracts) from source. To
+ ensure bytecode parity, the Solidity compiler configuration used should match
+ the following settings:
+
+ - Solidity version: 0.6.12
+ - Optimizer runs: 10000000 (Partners should attempt to use the same number of
+ optimizer runs, but may choose to reduce it if there are technical
+ limitations)
+
+ For suggested compiler settings that Circle uses, please refer to
+ [foundry.toml](../foundry.toml).
+
+2. Deploy the locally compiled FiatToken contracts. An overview of the
+ deployment process can be found [here](./deployment.md).
+3. Extract the compiler metadata used to generate the deployed contract's
+ bytecode and make it available to Circle to support the contract verification
+ process. The
+ [compiler metadata](https://docs.soliditylang.org/en/v0.6.12/metadata.html#contract-metadata)
+ is an autogenerated JSON file that can typically be found in the build
+ directory on the local machine.
+
+Circle’s repository is equipped with build tools and scripts that streamline the
+process above. The third-party team may refer to the steps listed
+[here](../README.md#deployment) to run the deployment.
+
+### Token Naming
+
+Circle has recommended
+[naming guidelines](https://brand.circle.com/d/M9z54TaEwsWL/stablecoins#/usdc-brand-guide/usdc-naming-guidelines)
+for the Token Name and Token Symbol attributes of a bridged USDC or EURC token
+contract that third-party teams are encouraged to follow. It is often the case
+that USDC and EURC are bridged from Ethereum to a new destination blockchain,
+and as such, the following is commonly used:
+
+USDC
+
+- Token Name: Bridged USDC (Third-Party Team)
+- Token Symbol: USDC.e
+
+EURC
+
+- Token Name: Bridged EURC (Third-Party Team)
+- Token Symbol: EURC.e
+
+Note that the text shown in parentheses above would be the third-party team’s
+company name.
+
+### IMPORTANT NOTE:
+
+- Once deployed, the bridged token contract must not be upgraded to a new or
+ different implementation at any time, outside of subsequent FiatToken versions
+ authored by Circle.
+- FiatToken has a number of one-time use initialization functions (listed below)
+ that are not permissioned, and therefore should be called during contract
+ deployment.
+ - Due to the proxy pattern used by FiatToken, after (or while) specifying the
+ current implementation that the proxy points to, these initialization
+ functions must be called to set the values correctly on the proxy's storage.
+ If not, then any caller could invoke them in the future.
+ - It is also recommended to call these functions directly on the
+ implementation contract itself, separately from the proxy, to disallow any
+ outside caller invoking them later. At the timing of writing, these
+ initialization functions include:
+ - [initialize](https://github.com/circlefin/stablecoin-evm/blob/405efc100c016ed1a437063b6274b4e24ea7b8b1/contracts/v1/FiatTokenV1.sol#L67)
+ - [initializeV2](https://github.com/circlefin/stablecoin-evm/blob/405efc100c016ed1a437063b6274b4e24ea7b8b1/contracts/v2/FiatTokenV2.sol#L37)
+ - [initializeV2_1](https://github.com/circlefin/stablecoin-evm/blob/405efc100c016ed1a437063b6274b4e24ea7b8b1/contracts/v2/FiatTokenV2_1.sol#L34)
+ - [initializeV2_2](https://github.com/circlefin/stablecoin-evm/blob/405efc100c016ed1a437063b6274b4e24ea7b8b1/contracts/v2/FiatTokenV2_2.sol#L41)
+
+There are a number of reference
+[deployment scripts](https://github.com/circlefin/stablecoin-evm/tree/35d66ae39f7038e30f04f87635f8bca6f8e38b04/migrations/direct)
+in the repository that demonstrate patterns for deploying USDC/EURC and
+configuring the implementation. For instance, there’s an
+[upgrader pattern](https://github.com/circlefin/stablecoin-evm/blob/35d66ae39f7038e30f04f87635f8bca6f8e38b04/migrations/versioned/8_deploy_v2_2_upgrader.js),
+where a smart contract sets the FiatToken implementation contract and calls the
+initialize functions within a single transaction.
+
+### Token Roles
+
+FiatToken uses a minter pattern, where minters can be configured via a master
+minter role to mint up to an allowed amount. One way to adapt the minter pattern
+to a bridged USDC or EURC token contract is to configure the destination bridge
+as a solo minter.
+
+The individual FiatToken roles (Owner, Pauser, Blacklister, MasterMinter) could
+also be assigned to the bridge, or some other upgradeable contract, as long as
+there's the ability to add a hook in the future to enable transferring the roles
+to Circle.
+
+If you would like more flexibility with permissioned minter configurations, you
+may want to explore the Controller and `MinterController`
+[contracts](https://github.com/circlefin/stablecoin-evm/tree/35d66ae39f7038e30f04f87635f8bca6f8e38b04/contracts/minting),
+which come together to form the `MasterMinter` pattern.
+
+#### Transferring the roles to Circle
+
+There are several USDC roles that will be transferred to a Circle-owned address
+at the time of the upgrade. Specifically these are:
+
+- Implementation Owner:
+ [defined](https://github.com/circlefin/stablecoin-evm/blob/657375471bff72afa5f625083bbab8003eb5f8c9/contracts/v1/Ownable.sol#L37)
+ in the implementation contract, the Owner can re-assign all other roles
+ (Owner, MasterMinter, Pauser, Rescuer, Blacklister).
+- ProxyAdmin:
+ [defined](https://github.com/circlefin/stablecoin-evm/blob/657375471bff72afa5f625083bbab8003eb5f8c9/contracts/upgradeability/AdminUpgradeabilityProxy.sol#L31)
+ in the proxy contract, the ProxyAdmin can re-assign the ProxyAdmin and perform
+ upgrades. By default, the proxy admin is not allowed to call any functions
+ defined by the implementation contract.
+
+It is up to the third-party team as to how they will secure and manage these
+roles as part of their original bridged USDC deployment and its ongoing use
+before a potential upgrade. For instance, the roles could be assigned to a
+secure multi-sig, or assigned to a smart contract (like the bridge), which can
+simplify the role transfer process. Some teams have opted to assign the
+ProxyAdmin role to a secure EOA / multi-sig wallet and assign the USDC roles to
+the bridge contract itself.
+
+If the roles are assigned to a smart contract, the contract must expose a
+function that Circle can call through a smart contract interaction to perform
+the role transfer at upgrade time. Automating this interaction can reduce manual
+errors and can enable atomic before and after checks that facilitate a smooth
+transfer.
+
+This function must have the following signature:
+
+```
+function transferUSDCRoles(address owner) external;
+```
+
+The function implementation details are left up to the partner, but it must:
+
+1. Be only callable by an address that Circle specifies closer to the time of
+ the upgrade. Note that this address will not necessarily be the same address
+ that is specified to call `burnLockedUSDC`.
+2. Transfer the Implementation Owner role to the address specified in the
+ `owner` parameter.
+3. Transfer the ProxyAdmin role to the function caller (if it is assigned to the
+ bridge).
+
+If the ProxyAdmin role is not assigned to the bridge contract, the partner
+should transfer the role to an address that Circle specifies closer to the time
+of the upgrade.
+
+Additionally, the partner is expected to remove all configured minters prior to
+(or concurrently with) transferring the roles to Circle.
+
+## For more information
+
+Please reach out on [our Discord](https://discord.com/invite/buildoncircle) if
+you have questions that were not addressed in this document. We value feedback
+and suggestions from the community to improve our documentation.
+
+---
+
+1. Bridged USDC Standard grants Circle the option, but not the obligation, to
+ obtain ownership of the token contract and upgrade to native USDC.
+ Additionally, Bridged USDC Standard must be incorporated prior to deploying a
+ bridged USDC token contract as it cannot be retroactively applied. The
+ requirements provided are for informational purposes only and will apply
+ should Circle choose to upgrade a particular form of bridged USDC to native
+ USDC. These requirements do not constitute an offer to upgrade a particular
+ form of bridged USDC. Circle’s decision to upgrade a particular form of
+ bridged USDC to native USDC may be subject to additional terms and
+ conditions. As noted in Section 8 of the
+ [USDC Terms of Use](https://www.circle.com/en/legal/usdc-terms), bridged
+ forms of USDC are subject to certain risks and are not issued by Circle. The
+ same conditions apply to EURC.
+2. The target blockchain will undergo Circle’s internal Blockchain Due Diligence
+ Process. That process involves reviews for both compliance and risk factors,
+ as well as coverage for legal and technology risks, prior to approval. The
+ diligence focuses on crypto and blockchain nuances, and an assessment of the
+ strategic, financial, operational, technology, legal, and regulatory risks
+ that are present.
diff --git a/doc/bridged_asset_automated_verification.md b/doc/bridged_asset_automated_verification.md
new file mode 100644
index 000000000..93cbb0261
--- /dev/null
+++ b/doc/bridged_asset_automated_verification.md
@@ -0,0 +1,106 @@
+# Bridged Asset Automated Verification
+
+This documentation is a step-by-step guide on using the automated workflow for
+bytecode verification for bridged token deployments. It also includes some
+common mistakes that have caused unsuccessful verification, and how to fix them.
+
+## Setup
+
+1. Clone the latest version of Circle's repo and set it up as instructed
+ [here](../README.md).
+
+2. Copy the [template](../verification_artifacts/input.template.json) by running
+ the following command
+
+ ```sh
+ $ cp verification_artifacts/input.template.json verification_artifacts/input.json
+ ```
+
+## Providing Input
+
+Please follow the instructions below on filling the file. It is required to
+provide the input for the latest FiatToken implementation contract
+(FiatTokenV2_2 as of writing), FiatTokenProxy, and the SignatureChecker library
+contract, all at once.
+
+1. Fill in the `input.json` file that you created. For each contract, the
+ required fields are:
+
+ - `contractAddress`
+ - `contractCreationTxHash`
+
+ You must also provide a standard EVM-compatible node URL in the field:
+
+ - `rpcUrl`
+
+ There are additional optional parameters for each contract that should only
+ be used if a contract cannot be verified using the required parameters alone.
+ The purpose of each optional parameter is described below::
+
+ - `verificationType`: by default, the verification type will be "partial".
+ This means that the metadata hash at the end of the runtime bytecode will
+ be verified separately via the metadata files generated below.
+ Alternatively, this field can be set to "full", but in that case, your
+ contract's metadata must match the metadata in this repo exactly. If this
+ parameter is set to "full", you may skip the metadata extraction described
+ in step 2.
+ - `useTracesForCreationBytecode`: a boolean value for whether or not to use
+ traces for pulling contract creation code. Setting this parameter to `true`
+ is only necessary if the contract was deployed _within_ a transaction, i.e.
+ it was deployed from another contract. Note that if this parameter is set
+ to `true`, the provided `rpcUrl` must support the `debug_traceTransaction`
+ JSON RPC method.
+ - `artifactType`: a string to indicate what artifact to use for verification
+ if the contract deployment does not match the current artifacts in the
+ repo. The options for this value can be found in
+ [alternativeArtficacts.ts](../scripts/hardhat/alternativeArtifacts.ts).
+ - `optimizerRuns`: an integer indicating the number of optimizer runs
+ specified when compiling the contract. This is only necessary to include if
+ your value does not match the one in [foundry.toml](../foundry.toml).
+
+2. Follow the steps [here](./metadata_extraction.md) to extract metadata for
+ each of the following contracts:
+
+ 1. extract FiatTokenV2_2 metadata to
+ `verification_artifacts/FiatTokenV2_2.json`
+ 2. extract FiatTokenProxy metadata to
+ `verification_artifacts/FiatTokenProxy.json`
+ 3. extract SignatureChecker metadata to
+ `verification_artifacts/SignatureChecker.json`
+
+ After this step, your local directory should look like
+
+ ```
+ stablecoin-evm
+ ├── verification_artifacts
+ │ ├── FiatTokenV2_2.json
+ │ ├── FiatTokenProxy.json
+ │ ├── SignatureChecker.json
+ │ └── input.json
+ ├── ...
+ ```
+
+ Note that the namings are strictly enforced by the verification script.
+
+## Steps for Verification
+
+1. Create a PR to Circle's public repo with the title prefixed with "**[B2N]**."
+2. Inform your point of contact at Circle that you have made a PR and wait for
+ an approval from Circle to run the GitHub action.
+3. Automated bytecode verification will run once the PR is checked and the
+ workflow is approved. From there, you can verify your results by seeing the
+ Checks section on the PR page. If verification fails, you may request for
+ another verification by submitting another commit to the same PR.
+4. Inform your point of contact at Circle once verification has succeeded.
+
+## Common Issues
+
+### Compiler Settings
+
+Please check your compiler settings and make sure everything, including
+optimizer runs, matches ours.
+
+### Metadata mismatch
+
+Do not format the metadata files--leave them as extracted. Formatting the file
+will result in a mismatching hash.
diff --git a/doc/celo.md b/doc/celo.md
new file mode 100644
index 000000000..45d3a74f8
--- /dev/null
+++ b/doc/celo.md
@@ -0,0 +1,54 @@
+# Circle's Celo `FiatToken` design
+
+This documentation explains the Celo-specific logic implemented by Circle for
+supporting `FiatToken` on the [Celo](https://celo.org/) network.
+
+The overall process for adding a new supported gas token to the Celo network is
+provided on
+[official documentation](https://docs.celo.org/learn/add-gas-currency), which
+covers the token implementation, oracle work required, and the governance
+proposal process.
+
+## Overview of debiting and crediting
+
+To see the interface, refer to `ICeloGasToken`. The Celo virtual machine calls
+`debitGasFees` and `creditGasFees` atomically as part of a transaction from the
+core Celo VM's state transition algorithm. See
+[the source code](https://github.com/celo-org/celo-blockchain/blob/3808c45addf56cf547581599a1cb059bc4ae5089/core/state_transition.go#L426-L526)
+from `celo-org/celo-blockchain`, notably on lines 481 (`payFees`) and 517
+(`distributeTxFees`).
+
+Only the Celo VM, which calls through `address(0)`, should be able to call
+`debitGasFees` and `creditGasFees`, which necessitates the use of a special
+modifier, an example of which can be found in
+[Celo's monorepo](https://github.com/celo-org/celo-monorepo/blob/fff103a6b5bbdcfe1e8231c2eef20524a748ed07/packages/protocol/contracts/common/CalledByVm.sol#L3).
+
+## Overview of `FiatTokenFeeAdapter`
+
+To see the interface, refer to `IFiatTokenFeeAdapter`. The Celo chain supports
+using ERC-20 tokens to pay for gas. For ERC-20 tokens that have a decimal field
+other than 18, the Celo chain uses the
+[FeeCurrencyAdapter](https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/11/packages/protocol/contracts-0.8/stability/FeeCurrencyAdapter.sol)
+strategy to ensure that the decimal conversion is fair. The deployed USDC
+adapters can be found in
+[Celo's official documentation](https://docs.celo.org/protocol/transaction/erc20-transaction-fees#tokens-with-adapters).
+
+## Deployment
+
+`FiatTokenCeloV2_2`'s deployment process is the same as the base `FiatTokenV2_2`
+[deployment process](./../README.md). Follow all the steps described in the
+deployment process, but be sure to run `deploy-fiat-token-celo` script instead
+of the base `deploy-fiat-token` script:
+
+```sh
+yarn forge:simulate scripts/deploy/celo/deploy-fiat-token-celo.s.sol --rpc-url
+```
+
+For the `FiatTokenFeeAdapter` deployment, be sure to fill in the required fields
+in the `.env` file. Namely, `FIAT_TOKEN_CELO_PROXY_ADDRESS`,
+`FEE_ADAPTER_PROXY_ADMIN_ADDRESS`, and `FEE_ADAPTER_DECIMALS` must be filled.
+Then, deploy by running the following command:
+
+```sh
+yarn forge:simulate scripts/deploy/celo/deploy-fee-adapter.s.sol --rpc-url
+```
diff --git a/doc/deployment.md b/doc/deployment.md
index 06181ed82..bedb7da1d 100644
--- a/doc/deployment.md
+++ b/doc/deployment.md
@@ -3,37 +3,42 @@
This is the process for deploying a new proxy and implementation (as opposed to
upgrading an existing proxy).
-Since the proxy uses `delegatecall` to forward calls to the implementation
-initialization of the contracts becomes a little tricky because we can not
+Since the proxy uses `delegatecall` to forward calls to the implementation,
+initialization of the contracts becomes a little tricky because we cannot
initialize fields in the implementation contract via the constructor. Instead
there is an initialize method in the implementation contract, which is publicly
available, but can only be called once per proxy.
## Deploying the implementation contract
-1. Deploy [FiatTokenV1](../contracts/FiatTokenV1.sol)
-2. Initialize the fields in FiatToken via the `initialize` method. The values
- are not important, but this will stop anyone else initializing the roles and
- trying to use it as a token or pass it off as a real CENTRE token.
- ```
+1. Deploy [FiatTokenV2_2](../contracts/v2/FiatTokenV2_2.sol)
+2. Initialize the fields in FiatTokenV2_2 via the `initialize*` methods. The
+ values are not important, but this will stop anyone else initializing the
+ roles and trying to use it as a token or pass it off as a real Circle token.
+
+ ```js
initialize(
- "",
- "",
- "",
- 0,
- throwawayAddress,
- throwawayAddress,
- throwawayAddress,
- throwawayAddress
- )
+ "",
+ "",
+ "",
+ 0,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS
+ );
+ initializeV2("");
+ initializeV2_1(THROWAWAY_ADDRESS);
+ initializeV2_2([], "");
```
+
3. Verify that all fields in the FiatToken have been initialized correctly and
- have the expected values. See [README.validate.md](../validate/validate.js).
+ have the expected values.
## Deploying a Proxy:
-1. Obtain addresses for the various contract roles from CENTRE ops. The keys for
- these addresses will be stored offline. The address needed are:
+1. Obtain addresses for the following contract roles. Ensure that the keys for
+ these addresses are securely stored.
```
admin
@@ -46,11 +51,11 @@ available, but can only be called once per proxy.
For details on what these roles can do, see the
[Token Design Doc](tokendesign.md)
-2. Deploy [FiatTokenProxy](../contracts/FiatTokenProxy.sol), passing the address
- of the deployed implementation contract to the constructor, which will
- initialize the `_implementation` field.
+2. Deploy [FiatTokenProxy](../contracts/v1/FiatTokenProxy.sol), passing the
+ address of the deployed implementation contract to the constructor, which
+ will initialize the `_implementation` field.
-3. The `admin` of the proxy contract defaults to msg.sender. You must either
+3. The `admin` of the proxy contract defaults to `msg.sender`. You must either
change the `admin` now, or send the remaining transactions from a different
address. The `admin` can only see methods in the Proxy, any method calls from
`admin` will not be forwarded to the implementation contract. The `admin`
@@ -59,47 +64,39 @@ available, but can only be called once per proxy.
```
changeAdmin(adminAddress)
-
```
-4. Initialize the proxy, via the `initialize` method. This call will get
+4. Initialize the proxy via the `initialize*` methods. This call will get
forwarded to the implementation contract, but since it is via `delegatecall`
it will run in the context of the Proxy contract, so the fields it is
- initializing will be stored it the storage of the Proxy. The values passed
+ initializing will be stored in the storage of the Proxy. The values passed
here are important, especially for the roles that will control the contract.
- These addresses should be obtained from CENTRE ops, and the keys will be
- stored offline.
- ```
+ ```js
initialize(
- "USD//C",
- "USDC",
- "USD",
- 6,
- masterMinterAddress,
- pauserAddress,
- blacklisterAddress,
- ownerAddress
- )
+ tokenName,
+ tokenSymbol,
+ tokenCurrency,
+ tokenDecimals,
+ masterMinterAddress,
+ pauserAddress,
+ blacklisterAddress,
+ ownerAddress
+ );
+ initializeV2(newTokenName);
+ initializeV2_1(lostAndFoundAddress);
+ initializeV2_2(accountsToBlacklist, newTokenSymbol);
```
5. Verify the fields have been properly initialized. Verification should be
performed independently by multiple people to make sure that the contract has
been deployed correctly. The following fields should be verified:
- - name, symbol, and currency are as expected
- - `decimals` is 6
- - `masterMinter` is the expected address
- - `pauser` is the expected address
- - `blacklister` is the expected address
- - `owner` is the expected address
- - `admin` is the expected address. Note that `admin` is not callable by
- anyone other than the admin, so this can be verified by calling
- `eth.getStorageAt(proxyAddress, 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b)`
- - `_implementation` is the address of the implementation contract. Note that
- `implementation` is not callable by anyone other than the admin, so this
- can be verified by calling
- `eth.getStorageAt(proxyAddress, 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3)`
+ - `admin` is the expected address
+ - `implementation` is the address of the implementation contract
+ - `name`, `symbol`, `currency` and `decimals` are as expected
+ - `version` is 2
+ - `owner`, `masterMinter`, `pauser`, `blacklister` are the expected addresses
- `totalSupply` is 0
- `initialized` is `true`
diff --git a/doc/masterminter.md b/doc/masterminter.md
new file mode 100644
index 000000000..bf7245f2c
--- /dev/null
+++ b/doc/masterminter.md
@@ -0,0 +1,121 @@
+# MasterMinter contract
+
+The MasterMinter is a governance contract. It delegates the functionality of the
+`masterMinter` role in the Circle FiatToken contract to multiple addresses. (The
+`masterMinter` role can add and remove minters from a FiatToken and set their
+allowances.) The MasterMinter contract delegates the minter management
+capability to `controllers`. Each `controller` manages exactly one `minter`, and
+a single `minter` may be managed by multiple `controllers`. This allows
+separation of duties (offline key management) and simplifies nonce management
+for warm transactions.
+
+Minters and FiatToken holders are not affected by replacing a `masterMinter`
+user address with a `MasterMinter` contract.
+
+# Roles
+
+The `MasterMinter` contract has the following roles:
+
+- `owner` - adds and removes controllers, sets the address of the
+ `minterManager`, and sets the owner.
+- `minterManager` - address of a contract (e.g. USDC) with a
+ `MinterManagementInterface`. The `minterManager` contract stores information
+ about minter allowances and which minters are enabled/disabled.
+- `controller` - each controller manages exactly one minter. A controller can
+ enable/disable its minter, and modify the minting allowance by calling
+ functions on the `MasterMinter` contract, and `MasterMinter` will call the
+ appropriate functions on the `minterManager`.
+- `minter` - each `minter` is managed by one or more `controller`. The `minter`
+ cannot perform any actions on the MasterMinter contract. It interacts only
+ with the FiatToken contract.
+
+# Interaction with FiatToken contract
+
+The `owner` of the FiatToken contract can set the `masterMinter` role to point
+to the address of the `MasterMinter` contract. This enables the `MasterMinter`
+contract to call minter management functions on the FiatToken contract:
+
+- `configureMinter(minter, allowance)` - Enables the `minter` and sets its
+ minting allowance.
+- `removeMinter(minter)` - Disables the `minter` and sets its minting allowance
+ to 0.
+- `isMinter(minter)` - Returns `true` if the `minter` is enabled, and `false`
+ otherwise.
+- `minterAllowance(minter)` - Returns the minting allowance of the `minter`.
+
+Together, these four functions are defined as the `MinterManagementInterface`.
+The `MasterMinter` contains the address of a `minterManager` that implements the
+`MinterManagementInterface`. The `MasterMinter` interacts with the FiatToken
+contract via the `minterManager`.
+
+When a `controller` calls a function on `MasterMinter`, the `MasterMinter` will
+call the appropriate function on the `FiatToken` contract on its behalf. Both
+the `MasterMinter` and the `FiatToken` do their own access control.
+
+# Function Summary
+
+- `configureController(controller, minter)` - The owner assigns the controller
+ to manage the minter. This allows the `controller` to call `configureMinter`,
+ `incrementMinterAllowance` and `removeMinter`. Note:
+ `configureController(controller, 0x00)` is forbidden because it has the effect
+ of removing the controller.
+- `removeController(controller)` - The owner disables the controller by setting
+ its `minter` to `0x00`.
+- `setMinterManager(minterManager)` - The owner sets a new contract to the
+ `minterManager` address. This has no effect on the old `minterManager`
+ contract. If the new `minterManager` does not implement the
+ `MinterManagementInterface` or does not give this instance of the
+ `MasterMinter` contract permission to call minter management functions then
+ the `controller` calls to `configureMinter`, `incrementMinterAllowance`, and
+ `removeMinter` will throw.
+- `configureMinter(allowance)` - A controller enables its minter and sets its
+ allowance. The `MasterMinter` contract will call the `minterManager` contract
+ on the `controller`'s behalf.
+- `incrementMinterAllowance` - A controller increments the allowance of an
+ enabled minter (`incrementMinterAllowance` will throw if the `minter`
+ is disabled). The `MasterMinter` contract will call the `minterManager`
+ contract on the `controller`'s behalf.
+- `removeMinter` - A controller disables a `minter`. The `MasterMinter` contract
+ will call the `minterManager` contract on the `controller`'s behalf.
+
+# Deployment
+
+The `MasterMinter` may be deployed independently of the `FiatToken` contract
+(e.g. USDC).
+
+- FiatToken then MasterMinter. Deploy `MasterMinter` and set the
+ `minterManager` to point to the `FiatToken` in the constructor. Then use the
+ `MasterMinter` `owner` role to configure at least one `controller` for each
+ existing `minter` in the `FiatToken`. Once the `MasterMinter` is fully
+ configured, use the `FiatToken` `owner` role to broadcast an
+ `updateMasterMinter` transaction setting `masterMinter` role to the
+ `MasterMinter` contract address.
+- MasterMinter then FiatToken. Deploy `MasterMinter` and set the
+ `minterManager` to point to address `0x00` in the constructor. Then deploy the
+ `FiatToken` and set the `masterMinter` to be the address of the `MasterMinter`
+ contract in the constructor. Next, use the `MasterMinter` `owner` to set the
+ `minterManager` and configure `controllers`.
+
+# Configuring the MasterMinter
+
+We recommend assigning at least two `controllers` to each `minter`.
+
+- AllowanceController. Use this `controller` to enable the `minter` with
+ a single `configureMinter` transaction, and then use it exclusively to sign
+ `incrementMinterAllowance` transactions. There may be multiple
+ `AllowanceControllers` that sign different size allowance increment
+ transactions.
+- SecurityController. Use this `controller` to sign a single
+ `removeMinter` transaction and store it for emergencies.
+
+This configuration allows the `removeMinter` transaction to be presigned as
+nonces for the `SecurityController` are deterministic, which reduces the time to
+respond when there's an issue. Broadcasting the `removeMinter` transaction will
+cause all future interactions from the `AllowanceController` to `throw`.
+
+# MasterMinter vs. MintController
+
+Creating a `MasterMinter` contract that _inherits_ from a `MintController`
+contract with no changes may seem like a curious design choice. This leaves open
+the possibility of creating other contracts that inherit from `MintController`
+without creating naming confusion due to their different functionality.
diff --git a/doc/metadata_extraction.md b/doc/metadata_extraction.md
new file mode 100644
index 000000000..81447d21d
--- /dev/null
+++ b/doc/metadata_extraction.md
@@ -0,0 +1,35 @@
+# Extracting Metadata
+
+Important note: please separately extract the metadata into their own JSON files
+for the FiatTokenProxy, FiatToken2_2 (at the time of writing), and
+SignatureChecker contracts.
+
+Depending on the development framework you are using, there are different ways
+to find the artifact metadata. The steps and general information are documented
+below.
+
+## Foundry
+
+Foundry automatically stores build information for each `.sol` file in a
+directory, typically the `out` directory unless specified otherwise in the
+`foundry.toml` file. For the contract `example.sol`, the metadata is stored in
+`out/example.sol/example.json` under the `rawMetadata` field, depending on the
+version of Foundry you're using. To retrieve the metadata, you can run the
+following command:
+
+```sh
+cat path/to/example.sol/example.json | jq -jr '.rawMetadata' > example.metadata.json
+```
+
+## Hardhat
+
+Hardhat stores the compiled output in the `artifacts` directory (or in the
+artifacts path specified in `hardhat.config.ts`), which includes two
+subdirectories, both of which are needed to extract metadata: `build-info` and
+`contracts`. The `build-info` directory contains files with hex IDs. You can
+output the metadata of `example.sol` to `example.metadata.json` by running the
+following command from root directory:
+
+```sh
+cat "$(jq -r '.buildInfo' path/to/artifacts/contracts/path/to/example.sol/example.dbg.json | sed 's|^\.\./\.\./\.\./|path/to/artifacts/|')" | jq -jr '.output.contracts["contracts/path/to/example.sol"].example.metadata' > example.json
+```
diff --git a/doc/tokendesign.md b/doc/tokendesign.md
index c0f405f94..7a986ffd3 100644
--- a/doc/tokendesign.md
+++ b/doc/tokendesign.md
@@ -1,6 +1,6 @@
-# CENTRE Fiat Token
+# Circle's FiatToken Design
-The CENTRE Fiat Token contract is an ERC-20 compatible token. It allows
+Circle's FiatToken contract is an ERC-20 compatible token. It allows
minting/burning of tokens by multiple entities, pausing all activity, freezing
of individual addresses, and a way to upgrade the contract so that bugs can be
fixed or features added.
@@ -18,41 +18,44 @@ functionality:
- `blacklister` - prevent all transfers to or from a particular address, and
prevents that address from minting or burning
- `owner` - re-assign any of the roles except for `admin`
-- `admin` - upgrade the contract, and re-assign itself
+- `admin` - manage the proxy-level functionalities such as switching the
+ implementation contract
+- `rescuer` - transfer any ERC-20 tokens that are locked up in the contract
-CENTRE will control the address of all roles except for minters, which will be
-controlled by the entities that CENTRE elects to make minters
+Circle will control the address of all roles.
## ERC-20
The `FiatToken` implements the standard methods of the ERC-20 interface with
some changes:
-- A blacklisted address will be unable to call `transfer`, `transferFrom`, or
- `approve`, and will be unable to receive tokens.
+- A blacklisted address will be unable to call `transfer` or `transferFrom`, and
+ will be unable to receive tokens.
+ - `approve` was not allowed for blacklisted addresses in FiatToken versions
+ <2.2 but available in versions 2.2+. See ["Blacklisting"](#blacklisting)
+ section for more details.
- `transfer`, `transferFrom`, and `approve` will fail if the contract has been
paused.
## Issuing and Destroying tokens
-The Fiat Token allows multiple entities to create and destroy tokens. These
-entities will have to be members of CENTRE, and will be vetted by CENTRE before
-they are allowed to create new tokens. CENTRE will not mint any tokens itself,
-it will approve members to mint and burn tokens.
-
-Each `minter` has a `mintingAllowance`, which CENTRE configures. The
-`mintingAllowance` is how many tokens that minter may issue, and as a `minter`
-issues tokens, its `mintingAllowance` declines. CENTRE will periodically reset
-the `mintingAllowance` as long as a `minter` remains in good standing with
-CENTRE and maintains adequate reserves for the tokens it has issued. The
-`mintingAllowance` is to limit the damage if any particular `minter` is
+The FiatToken contract allows multiple entities to create and destroy tokens.
+These entities will have to be members of Circle, and will be vetted by Circle
+before they are allowed to create new tokens.
+
+Each `minter` has a `minterAllowance`, which Circle configures. The
+`minterAllowance` is how many tokens that minter may issue, and as a `minter`
+issues tokens, its `minterAllowance` declines. Circle will periodically reset
+the `minterAllowance` as long as a `minter` remains in good standing with Circle
+and maintains adequate reserves for the tokens it has issued. The
+`minterAllowance` is to limit the damage if any particular `minter` is
compromised.
### Adding Minters
-CENTRE adds minters via the `configureMinter` method. When a minter is
-configured a `mintingAllowance` is specified, which is the number of tokens that
-address is allowed to mint. As a `minter` mints tokens, the `mintingAllowance`
+Circle adds minters via the `configureMinter` method. When a minter is
+configured a `minterAllowance` is specified, which is the number of tokens that
+address is allowed to mint. As a `minter` mints tokens, the `minterAllowance`
will decline.
- Only the `masterMinter` role may call configureMinter.
@@ -60,13 +63,13 @@ will decline.
### Resetting Minting Allowance
The `minters` will need their allowance reset periodically to allow them to
-continue minting. When a `minter`'s allowance is low, CENTRE can make another
-call to `configureMinter` to reset the `mintingAllowance` to a higher value.
+continue minting. When a `minter`'s allowance is low, Circle can make another
+call to `configureMinter` to reset the `minterAllowance` to a higher value.
### Removing Minters
-CENTRE removes minters via the `removeMinter` method. This will remove the
-`minter` from the list of `minters` and set its `mintingAllowance` to 0. Once a
+Circle removes minters via the `removeMinter` method. This will remove the
+`minter` from the list of `minters` and set its `minterAllowance` to 0. Once a
`minter` is removed it will no longer be able to mint or burn tokens.
- Only the `masterMinter` role may call `removeMinter`.
@@ -76,7 +79,7 @@ CENTRE removes minters via the `removeMinter` method. This will remove the
A `minter` mints tokens via the `mint` method. The `minter` specifies the
`amount` of tokens to create, and a `_to` address which will own the newly
created tokens. A `minter` may only mint an amount less than or equal to its
-`mintingAllowance`. The `mintingAllowance` will decrease by the amount of tokens
+`minterAllowance`. The `minterAllowance` will decrease by the amount of tokens
minted, and the balance of the `_to` address and `totalSupply` will each
increase by `amount`.
@@ -93,11 +96,11 @@ A `minter` burns tokens via the `burn` method. The `minter` specifies the
`amount` of tokens to burn, and the `minter` must have a `balance` greater than
or equal to the `amount`. Burning tokens is restricted to `minter` addresses to
avoid accidental burning of tokens by end users. A `minter` with a
-`mintingAllowance` of 0 is allowed to burn tokens. A `minter` can only burn
+`minterAllowance` of 0 is allowed to burn tokens. A `minter` can only burn
tokens which it owns. When a minter burns tokens, its balance and the
totalSupply are reduced by `amount`.
-Burning tokens will not increase the mintingAllowance of the address doing the
+Burning tokens will not increase the minterAllowance of the address doing the
burning.
- Only a minter may call burn.
@@ -111,11 +114,19 @@ burning.
## Blacklisting
Addresses can be blacklisted. A blacklisted address will be unable to transfer
-tokens, approve, mint, or burn tokens.
+tokens, mint, or burn tokens.
+
+In FiatToken versions <2.2, A blacklisted address is unable to call `approve`,
+`increaseAllowance`, `decreaseAllowance`, or authorize future pull payments
+using `permit`. Nor can it be authorized to pull payments from other addresses.
+This has been changed in v2.2 where a blacklisted address can perform the above
+functions. But they are still blocked from transferring the assets in any way.
+and therefore any operations on modifying the allowance of blacklisted addresses
+are considered meaningless.
### Adding a blacklisted address
-CENTRE blacklists an address via the `blacklist` method. The specified `account`
+Circle blacklists an address via the `blacklist` method. The specified `account`
will be added to the blacklist.
- Only the `blacklister` role may call `blacklist`.
@@ -123,7 +134,7 @@ will be added to the blacklist.
### Removing a blacklisted address
-CENTRE removes an address from the blacklist via the `unblacklist` method. The
+Circle removes an address from the blacklist via the `unblacklist` method. The
specified `account` will be removed from the blacklist.
- Only the `blacklister` role may call `unblacklist`.
@@ -136,11 +147,11 @@ serious key compromise. All transfers, minting, burning, and adding minters will
be prevented while the contract is paused. Other functionality, such as
modifying the blacklist, removing minters, changing roles, and upgrading will
remain operational as those methods may be required to fix or mitigate the issue
-that caused CENTRE to pause the contract.
+that caused Circle to pause the contract.
### Pause
-CENTRE will pause the contract via the `pause` method. This method will set the
+Circle will pause the contract via the `pause` method. This method will set the
paused flag to true.
- Only the `pauser` role may call pause.
@@ -149,7 +160,7 @@ paused flag to true.
### Unpause
-CENTRE will unpause the contract via the `unpause` method. This method will set
+Circle will unpause the contract via the `unpause` method. This method will set
the `paused` flag to false. All functionality will be restored when the contract
is unpaused.
@@ -157,17 +168,44 @@ is unpaused.
- Unpausing emits an `Unpause()` event
+## Meta transactions compatibility
+
+### ERC-2612
+
+The contract is compatible with
+[ERC-2612](https://eips.ethereum.org/EIPS/eip-2612). Users may update their
+ERC-20 allowances by signing a `permit` message and passing the signed message
+to a relayer who will execute the on-chain transaction, instead of submitting a
+transaction themselves.
+
+### ERC-3009
+
+The contract is compatible with
+[ERC-3009](https://eips.ethereum.org/EIPS/eip-3009). Users may transfer assets
+to another user by signing an EIP-3009 authorization and passing the
+authorization to a relayer who will execute the authorization on chain, instead
+of submitting a transaction themselves.
+
+### Signature Validation schemes
+
+The contract supports signature validation via:
+
+1. ECDSA signatures for Externally Owned Accounts (EOAs)
+2. [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) for ERC-1271 compatible
+ Smart Contract Wallets
+
## Upgrading
-The Fiat Token uses the zeppelinos Unstructured-Storage Proxy pattern
-[https://docs.zeppelinos.org/docs/upgradeability_AdminUpgradeabilityProxy.html].
-[FiatTokenV1.sol](../contracts/FiatTokenV1.sol) is the implementation, the
-actual token will be a Proxy contract
-([FiatTokenProxy.sol](../contracts/FiatTokenProxy.sol)) which will forward all
-calls to `FiatToken` via delegatecall. This pattern allows CENTRE to upgrade the
-logic of any deployed tokens seamlessly.
+The FiatTokenProxy contract uses the zeppelinos Unstructured-Storage Proxy
+pattern
+[https://github.com/zeppelinos/zos-lib/blob/8a16ef3ad17ec7430e3a9d2b5e3f39b8204f8c8d/contracts/upgradeability/AdminUpgradeabilityProxy.sol].
+[FiatTokenV2_2.sol](../contracts/v2/FiatTokenV2_2.sol) is the implementation,
+the actual token will be a Proxy contract
+([FiatTokenProxy.sol](../contracts/v1/FiatTokenProxy.sol)) which will forward
+all calls to `FiatToken` via delegatecall. This pattern allows Circle to upgrade
+the logic of any deployed tokens seamlessly.
-- CENTRE will upgrade the token via a call to `upgradeTo` or `upgradeToAndCall`
+- Circle will upgrade the token via a call to `upgradeTo` or `upgradeToAndCall`
if initialization is required for the new version.
- Only the `admin` role may call `upgradeTo` or `upgradeToAndCall`.
@@ -200,3 +238,8 @@ reassign all roles (including itself) except for the `admin` role.
- `transferOwnership` updates the `owner` role to a new address.
- `transferOwnership` may only be called by the `owner` role.
+
+### Rescuer
+
+- `updateRescuer` updates the `rescuer` role to a new address.
+- `updateRescuer` may only be called by the `owner` role.
diff --git a/doc/upgrade.md b/doc/upgrade.md
index ae7578789..386c58ede 100644
--- a/doc/upgrade.md
+++ b/doc/upgrade.md
@@ -8,11 +8,24 @@ token, and pointing an existing proxy to the upgraded token.
An upgraded token can have:
1. New logic (functions)
-2. New fields (data)
-3. New logic and new fields
+2. New state variables (data)
+3. New logic and new state variables
+4. Renamed state variables
+5. Updated logic for existing functions
Each situation is addressed in a section below.
+> **_IMPORTANT_**: Do not remove existing state variables or modify the
+> inheritance order of contracts. Storage addresses for contract states are
+> defined during compilation and follow a sequential order based on the
+> declaration of state variables. Removing a state variable may cause other
+> variables to read/write from the wrong storage address which is dangerous.
+>
+> Be cautious when working with storage slots. Before upgrading, ensure that
+> storage addresses for existing state variables have not changed. You may rely
+> on [storageSlots.behavior.ts](../test/helpers/storageSlots.behavior.ts) to
+> validate this behavior.
+
### New Logic Only
A template for the next upgraded contract for new logic is kept in /contracts
@@ -20,7 +33,7 @@ with the file name FiatTokenV[X].sol where X is the version number. The upgraded
contract _must_ inherit from the current contract. For example, if upgrading
from version 1 to version 2, the contract would have the format:
-```
+```solidity
import './FiatTokenV1.sol';
/**
@@ -38,29 +51,30 @@ All that remains is to add the new logic (functions) as part of the body
_functions_ will not be inherited in subsequent contract versions and should be
added with care.
-### New Fields Only
-
-Adding new fields requires inheriting from the prior version of the contract as
-done in [New Logic](#new-logic-only). In addition, the new contract requires
-declaring new data fields and, if the data fields must be initialized to
-non-default values, adding initialization logic for the new fields. New
-variables added _must_ be declared as type `internal` or `public`, `private` can
-never be used. Note that `private` _functions_ will also not be inherited in
-subsequent contract versions and should be added with care. Also note that
-inline initialization of variables as part of declaration has no effect as the
-proxy never executes this code (for example, bool public newBool = true is not
-in fact initialized to true). If possible, new fields should be added that can
-start with default solidity values and do not need initialization. However, if
-any new fields require initialization to non-default values, the new token must
-add an _initialize_ function and a _initV[X]_ function, where X is the version
-of the contract. The initialization function allows the contract to be deployed
-from scratch and initialize all variables declared in the new contract and in
-prior contracts. The initV[X] function allows the contract to initialize only
-the new variables added in the new contract. A template is shown below for
-upgrading from version 1 to version 2. In the example, we add variables newBool,
-newAddress, and newUint, which would be replaced with the real variables added.
-
-```
+### New State Variables Only
+
+Adding new state variables requires inheriting from the prior version of the
+contract as done in [New Logic](#new-logic-only). In addition, the new contract
+requires declaring new state variables and, if the state variables must be
+initialized to non-default values, adding initialization logic for the new state
+variables. New variables added _must_ be declared as type `internal` or
+`public`, `private` can never be used. Note that `private` _functions_ will also
+not be inherited in subsequent contract versions and should be added with care.
+Also note that inline initialization of variables as part of declaration has no
+effect as the proxy never executes this code (for example, bool public newBool =
+true is not in fact initialized to true). If possible, new state variables
+should be added that can start with default Solidity values and do not need
+initialization. However, if any new state variables require initialization to
+non-default values, the new token must add an _initialize_ function and a
+_initV[X]_ function, where X is the version of the contract. The initialization
+function allows the contract to be deployed from scratch and initialize all
+variables declared in the new contract and in prior contracts. The initV[X]
+function allows the contract to initialize only the new variables added in the
+new contract. A template is shown below for upgrading from version 1 to
+version 2. In the example, we add variables newBool, newAddress, and newUint,
+which would be replaced with the real variables added.
+
+```solidity
import './FiatTokenV1.sol';
/**
@@ -106,18 +120,63 @@ _Note the addition of a new initializedV[X] variable that is checked and set in
initV[X]._ _Note the structure of initialized that uses a super call with
previously set parameters as well as a call to initV[X]._
-### New Logic and New Fields
+### New Logic and New State Variables
+
+The case requires the same steps as
+[New State Variables](#new-state-variables-only) plus the addition of new
+functions as done in [New Logic](#new-logic-only).
+
+### Updated Logic
+
+The logic in existing functions may be updated, but it should be done only if it
+does not cause breaking changes to users of the contract and it is absolutely
+necessary. This can be done by finding the function declaration in the existing
+contracts, marking the function as `virtual`, and `override` the function in the
+upgraded contract.
+
+```solidity
+contract FiatTokenV1 {
+ ...
+
+ function foo() external virtual pure returns (uint256) {
+ return 1;
+ }
+}
+```
+
+```solidity
+import './FiatTokenV1.sol';
+
+/**
+ \* @title FiatTokenV2
+ \* @dev ERC20 Token backed by fiat reserves
+ **/
+contract FiatTokenV2 is FiatTokenV1 {
+ ...
+
+ function foo() external override pure returns (uint256) {
+ return 2;
+ }
+}
+```
+
+### Renamed State Variables
-The case requires the same steps as [New Fields](#new-fields-only) plus the
-addition of new functions as done in [New Logic](#new-logic-only).
+State variables may be renamed to increase clarity or readability. This may be
+useful if there are state variables that have become unused but cannot be safely
+removed. Deprecating the variable can be done by finding the variable
+declaration in existing contracts, prefixing the variable with `deprecated` and
+replacing references to the variable with the new name.
## Upgraded Token Deployment
Deployment can be done in the following steps:
-1. Write any new logic and new fields in the new contract (as described above)
-2. Test any new fields and logic added to the contract (including positive,
- negative, and extended tests following the current testing strategy)
+1. Write any new logic and new state variables in the new contract (as described
+ above)
+2. Test any new state variables and logic added to the contract (including
+ positive, negative, and extended tests following the current testing
+ strategy)
3. Ensure the test suite has run on the final version of the new contract with
added tests and that the test suite passes with 100% code coverage
4. Complete any external audits as deemed necessary
@@ -131,8 +190,8 @@ Deployment can be done in the following steps:
## Upgrading the Proxy to point to the UpgradedToken
The proxy must be pointed to the new upgraded token. This is accomplished two
-ways depending on whether only new logic was added or if new fields (and
-possibly new logic) were added.
+ways depending on whether only new logic was added or if new state variables
+(and possibly new logic) were added.
### Upgrading if _ONLY_ New Logic Added
@@ -140,30 +199,20 @@ possibly new logic) were added.
address of the new upgraded token.
2. Broadcast the transaction
3. Check that the implementation field of the proxy matches the address of the
- upgraded token by calling web3.eth.getStorageAt(proxy.address, implSlot),
- where implSlot is defined in the contract as a hardcoded field. As of CENTRE
- Fiat Token v1.0.0 that slot is
- 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b.
- Alternatively, getImplementation may be called on the proxy with the
- adminAccount.
+ upgraded token by calling the `implementation` method
4. If the address in 3) does not match, it is likely a wrong address was used.
Repeat the process from step 1).
-### Upgrading if New Fields (and possibly new Logic) Added
+### Upgrading if New State Variables (and possibly new logic) Added
1. Prepare an upgradeToAndCall transaction from the adminAccount parameterized
with the address of the new upgraded token and an internal call to invoke
- initV[X] with the new data fields.
+ initV[X] with the new data state variables.
2. Broadcast the transaction
3. Check that the implementation field of the proxy matches the address of the
- upgraded token by calling web3.eth.getStorageAt(proxy.address, implSlot),
- where implSlot is defined in the contract as a hardcoded field. As of CENTRE
- Fiat Token v1.0.0 that slot is
- 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b.
- Alternatively, getImplementation may be called on the proxy with the admin
- account.
+ upgraded token by calling the `implementation` method
4. If the address in 3) does not match, it is likely a wrong address was used.
Repeat the process from step 1).
-5. Verify that the new fields were set correctly as done in _Deployment
+5. Verify that the new state variables were set correctly as done in _Deployment
Instructions_ [verification](deployment.md)
6. If verification fails, restart the process from step 1)
diff --git a/doc/v2.2_upgrade.md b/doc/v2.2_upgrade.md
new file mode 100644
index 000000000..3df037782
--- /dev/null
+++ b/doc/v2.2_upgrade.md
@@ -0,0 +1,153 @@
+# V2.2 Upgrade
+
+### Prerequisites
+
+1. Deployer Key ("Deployer Key")
+2. Proxy Admin Key ("Admin Key")
+3. A list of currently blacklisted accounts stored in `blacklist.remote.json`
+
+### Preparation
+
+1. Get the contract creation block number for the target FiatTokenProxy contract
+ either using a block explorer, or the command below.
+
+ ```sh
+ $ yarn hardhat getContractCreationBlock --network ${NETWORK} ${FiatTokenProxy address}
+ ```
+
+2. Get a list of accounts that are currently blacklisted on the target
+ FiatTokenProxy contract by running the following command. `startBlockNumber`
+ should be set to the contract creation block number of the target
+ FiatTokenProxy contract.
+
+ ```sh
+ $ yarn hardhat downloadBlacklistedAccounts --network ${NETWORK} \
+ --proxy-address ${FiatTokenProxy address} \
+ --start-block-number ${startBlockNumber}
+ ```
+
+### Steps
+
+1. From project root folder, make a copy of `.env.example` and name the file
+ `.env`. Ensure `.env` is configured with the correct values. The environment
+ variables `PROXY_ADMIN_ADDRESS`, `FIAT_TOKEN_PROXY_ADDRESS` must be defined.
+
+2. Set the `NETWORK` variable to the network that you will like to deploy to in
+ your terminal.
+
+ ```sh
+ $ NETWORK=;
+ ```
+
+3. Look for the `deploy-impl-and-upgrader.s.sol` script in
+ [`./scripts/deploy/`](../scripts/deploy/). Ensure the the following variables
+ are correctly configured in your local `.env` file:
+
+ ```sh
+ $ DEPLOYER_PRIVATE_KEY=
+ $ FIAT_TOKEN_PROXY_ADDRESS=
+ $ PROXY_ADMIN_ADDRESS=
+ $ LOST_AND_FOUND_ADDRESS=
+ $ TOKEN_SYMBOL=
+
+ # [Optional] Fill in if an implementation contract already exists
+ $ FIAT_TOKEN_IMPLEMENTATION_ADDRESS=
+ ```
+
+4. Ensure that the `blacklist.remote.json` file in the project root folder is
+ configured with the correct list of addresses to blacklist.
+
+5. Run foundry deploy simulation by running the following command
+
+ ```sh
+ yarn forge:simulate scripts/deploy/deploy-impl-and-upgrader.s.sol --rpc-url $NETWORK
+ ```
+
+ Validate all fields are filled in correctly.
+
+ **_NOTE:_** For additional information, you may also validate each of the
+ transactions to be broadcasted by checking the
+ `./broadcast/deploy-impl-and-upgrader.s.sol/:chainId/dry-run` folder that
+ gets auto created in your local machine.
+
+6. Deploy the contracts by running the following command
+
+ ```sh
+ yarn forge:broadcast scripts/deploy/deploy-impl-and-upgrader.s.sol --rpc-url $NETWORK
+ ```
+
+7. Verify the contracts on an Etherscan flavored block explorer by running the
+ following command. Ensure that `ETHERSCAN_KEY` is set in the `.env` file.
+
+ ```sh
+ yarn forge:verify scripts/deploy/deploy-impl-and-upgrader.s.sol --rpc-url $NETWORK
+ ```
+
+8. Verify that the upgrader contract is deployed correctly. Verify that the
+ values returned by `proxy()`, `implementation()` and `newProxyAdmin()` on the
+ `V2_2Upgrader` contract are correct either using a block explorer, or the
+ command below.
+
+ ```sh
+ $ yarn compile
+ $ yarn hardhat readValuesFromContract --network ${NETWORK} \
+ --contract-name V2_2Upgrader \
+ --contract-address ${V2_2Upgrader address} \
+ proxy implementation newProxyAdmin
+ ```
+
+9. Verify that the `V2_2UpgraderHelper` contract is deployed correctly. Retrieve
+ the address from the `V2_2Upgrader` contract `helper()` method, and verify
+ that the return values of each view methods correspond with the
+ `FiatTokenProxy` contract to be upgraded either using a block explorer, or
+ the command below.
+
+ ```sh
+ $ yarn compile
+ $ yarn hardhat readValuesFromContract --network ${NETWORK} \
+ --contract-name V2_2Upgrader \
+ --contract-address ${V2_2Upgrader address} \
+ helper
+ $ yarn hardhat readValuesFromContract --network ${NETWORK} \
+ --contract-name V2_2UpgraderHelper \
+ --contract-address ${V2_2UpgraderHelper address} \
+ name symbol decimals currency masterMinter fiatTokenOwner pauser blacklister version DOMAIN_SEPARATOR rescuer paused totalSupply
+
+ # Compare results above with
+ $ yarn hardhat readValuesFromContract --network ${NETWORK} \
+ --contract-name FiatTokenV2_1 \
+ --contract-address ${FiatTokenProxy address} \
+ name symbol decimals currency masterMinter fiatTokenOwner pauser blacklister version DOMAIN_SEPARATOR rescuer paused totalSupply
+ ```
+
+10. Verify that the list of accounts to blacklist is correct, and is set
+ correctly in the upgrader contract. Run the following command to check the
+ list.
+
+ ```sh
+ $ yarn hardhat validateAccountsToBlacklist --network=${NETWORK} \
+ --proxy-address ${FiatTokenProxy address} \
+ --upgrader-address ${V2_2Upgrader address}
+ ```
+
+11. Using the Admin Key, transfer the proxy admin role to the `V2_2Upgrader`
+ contract address by calling `changeAdmin(address)` method on the
+ `FiatTokenProxy` contract.
+
+12. Send 0.20 FiatToken (eg USDC) to the `V2_2Upgrader` contract address.
+ (200,000 tokens)
+
+13. Using the Deployer Key, call `upgrade()` (`0xd55ec697`) method on the
+ `V2_2Upgrader`.
+
+#### IF THE UPGRADE TRANSACTION SUCCEEDS
+
+- Verify that the proxy admin role is transferred back to the Admin Key.
+- No further action needed.
+
+#### IF THE UPGRADE TRANSACTION FAILS
+
+- If the transaction fails, any state change that happened during the `upgrade`
+ function call will be reverted.
+- Call `abortUpgrade()` (`0xd8f6a8f6`) method on the `V2_2Upgrader` contract to
+ tear it down.
diff --git a/doc/v2_upgrade.md b/doc/v2_upgrade.md
deleted file mode 100644
index 2a7fd2233..000000000
--- a/doc/v2_upgrade.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# V2 Upgrade
-
-### Prerequisites
-
-1. Truffle Deployer Key ("Deployer Key")
-2. Proxy Admin Key ("Admin Key")
-
-### Steps
-
-1. Ensure `config.js` file in the project root folder is configured correctly
- with correct values.
-
-2. Run Truffle migrations using the Deployer Key, and get the address of the
- newly deployed `V2Upgrader` contract. The address is highlighted (`>>><<<`)
- to prevent accidental copying-and-pasting of an incorrect address.
-
- ```
- $ yarn migrate --network mainnet --f 3 --to 4
- ...
- ...
- Dry-run successful. Do you want to proceed with real deployment? >> (y/n): y
- ...
- ...
- >>>>>>> Deployed V2Upgrader at 0x12345678 <<<<<<<
- ```
-
-3. Verify that the upgrader contract is deployed correctly. Verify that the
- values returned by `proxy()`, `implementation()`, `newProxyAdmin()`, and
- `newName()` on the `V2Upgrader` contract are correct.
-
-4. Using the Admin Key, transfer the proxy admin role to the `V2Upgrader`
- contract address by calling `changeAdmin(address)` method on the
- `FiatTokenProxy` contract.
-
-5. Send 0.20 USDC to the `V2Upgrader` contract address. (200,000 tokens)
-
-6. Using the Deployer Key, call `upgrade()` (`0xd55ec697`) method on the
- `V2Upgrader`.
-
-#### IF THE UPGRADE TRANSACTION SUCCEEDS
-
-- Verify that the proxy admin role is transferred back to the Admin Key.
-- No further action needed.
-
-#### IF THE UPGRADE TRANSACTION FAILS
-
-- If the transaction fails, any state change that happened during the `upgrade`
- function call will be reverted.
-- Call `abortUpgrade()` (`0xd8f6a8f6`) method on the `V2Upgrader` contract to
- tear it down.
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index a79331bbc..000000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-version: '2.1'
-services:
-
-##################################
-### Ganache (ethereum-testrpc) ###
-##################################
- ganache:
- build:
- context: .
- dockerfile: Dockerfile.ganache
- ports:
- - "8545:8545"
-
-##################################
-### Truffle ###
-##################################
- truffle:
- build:
- context: .
- dockerfile: Dockerfile.truffle
- volumes:
- - ./:/usr/local/solidity
- working_dir: /usr/local/solidity
- command: compile
- depends_on:
- - "ganache"
-
diff --git a/echidna_tests/README.md b/echidna_tests/README.md
deleted file mode 100644
index 7558073b2..000000000
--- a/echidna_tests/README.md
+++ /dev/null
@@ -1,40 +0,0 @@
-#Setup
-
-1. Install the full version of
- [solc](http://solidity.readthedocs.io/en/v0.4.24/installing-solidity.html)
- via homebrew (not npm).
-
-2. Clone the echidna repository by running:
- `git submodule add git@github.com:trailofbits/echidna.git`
- `git submodule update --init --recursive` Make sure that the `echidna`
- directory appears in your project root directory. (echidna is included in
- .gitignore)
-
-3. Install stack: `brew install haskell-stack`
-
-4. Run the following commands from inside the echidna directory. Ignore all
- warnings. `stack upgrade` `stack setup` `stack install`
-
-5. If this gives you errors involving 'readline' on MacOS, try running:
- `brew install readline` `brew link readline --force`
- `export LDFLAGS=-L/usr/local/opt/readline/lib`
- `export CPPFLAGS=-I/usr/local/opt/readline/include`
- `stack install readline --extra-include-dirs=/usr/local/opt/readline/include --extra-lib-dirs=/usr/local/opt/readline/lib`
- `stack install`
-
-6. Add `/Users/$(whoami)/.local/bin` to your `PATH` variable:
- `export PATH=$PATH:/Users/$(whoami)/.local/bin`
-
-7. Open `echidna_tests/config.yaml` in a text editor and replace the words
- `REPLACE_WITH_PWD` with the path to the project root directory. To get this
- path, run `echo $PWD`.
-
-8. The echidna_tests suite contains negative and positive test files.
-
-- To run the positive tests, open `config.yaml` and set the field `returnType`
- to `Success`. Then, run the following command from the project root directory:
- `echidna-test echidna_tests/positive.sol Test --config="echidna_tests/config.yaml"`
-- To run the negative tests, open `config.yaml` and set the field `returnType`
- to `Fail or Throw`. Then, run the following command from the project root
- directory:
- `echidna-test echidna_tests/negative.sol Test --config="echidna_tests/config.yaml"`
diff --git a/echidna_tests/config.yaml b/echidna_tests/config.yaml
deleted file mode 100644
index f044dc9cb..000000000
--- a/echidna_tests/config.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-#Arguments to solc
-# PLEASE CHANGE THE LINE BELOW to include the absolute path of your working directory.
-solcArgs: openzeppelin-solidity=REPLACE_WITH_PWD/node_modules/openzeppelin-solidity zos-lib=REPLACE_WITH_PWD/node_modules/zos-lib contracts=REPLACE_WITH_PWD/contracts
-#Choose the number of epochs to use in coverage-guided testing
-#epochs: 2
-#Set the gas limit for each test
-#gasLimit: 0xfffff
-#Number of tests that will run for each property
-testLimit: 10000
-#Max call sequence length
-range: 10
-#Contract's address in the EVM
-contractAddr: 0x00a329c0648769a73afac7f9381e08fb43dbea72
-#Sender's address in the EVM
-sender: 0x00a329c0648769a73afac7f9381e08fb43dbea70
-#List of addresses that will be used in all tests
-addrList:
- - 0x00a329c0648769a73afac7f9381e08fb43dbea70
- - 0x00a329c0648769a73afac7f9381e08fb43dbea72
- - 0x67518339e369ab3d591d3569ab0a0d83b2ff5198
- - 0x0
-#Shrink Limit
-shrinkLimit: 1000
-#Test Prefix
-prefix: echidna_
-#Print full coverage
-printCoverage: false
-#Return Type
-# - Success: all tests should return true
-# - Fail: all tests should return false
-# - Throw: all tests should revert
-# - Fail or Throw: all tests should either return false or revert
-returnType: Fail or Throw
diff --git a/echidna_tests/negative.sol b/echidna_tests/negative.sol
deleted file mode 100644
index 51c6f1f84..000000000
--- a/echidna_tests/negative.sol
+++ /dev/null
@@ -1,57 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "contracts/FiatTokenV1.sol";
-
-contract Test is FiatTokenV1 {
- //Note: These are special addresses used by echidna––please don't change.
- address testerAddr = 0x00a329c0648769a73afac7f9381e08fb43dbea70;
- address otherAddr = 0x67518339e369ab3d591d3569ab0a0d83b2ff5198;
- address ownerAddr = 0x00a329c0648769a73afac7f9381e08fb43dbea72;
- uint256 initial_totalSupply = 1000000000;
-
- constructor() public {
- /* config.yaml sets this contract's address to ownerAddr, so we
- need to initialize all the contract roles to this address so that calls
- from the contract pass funtion modifiers.*/
- initialize(
- "Test",
- "",
- "",
- 6,
- ownerAddr,
- ownerAddr,
- ownerAddr,
- ownerAddr
- );
- configureMinter(ownerAddr, initial_totalSupply);
- mint(testerAddr, initial_totalSupply / 2);
- require(balanceOf(testerAddr) == initial_totalSupply / 2);
- mint(otherAddr, initial_totalSupply / 2);
- require(balanceOf(otherAddr) == initial_totalSupply / 2);
- }
-
- function echidna_failed_transaction() public returns (bool) {
- uint256 balance = balanceOf(testerAddr);
- transfer(testerAddr, balance + 1);
- return (true);
- }
-
- function echidna_self_approve_and_failed_transferFrom_to_zero()
- public
- returns (bool)
- {
- uint256 balance = balanceOf(testerAddr);
- approve(testerAddr, 0);
- approve(testerAddr, balance);
- transferFrom(testerAddr, 0x0, balance);
- return (true);
- }
-
- function echidna_multiple_approves() public returns (bool) {
- transfer(ownerAddr, 1);
- uint256 balance = balanceOf(ownerAddr);
- approve(testerAddr, balance);
- approve(testerAddr, balance);
- return (allowed[ownerAddr][testerAddr] == balance);
- }
-}
diff --git a/echidna_tests/positive.sol b/echidna_tests/positive.sol
deleted file mode 100644
index e9caad699..000000000
--- a/echidna_tests/positive.sol
+++ /dev/null
@@ -1,80 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "contracts/FiatTokenV1.sol";
-
-contract Test is FiatTokenV1 {
- //Note: These are special addresses used by echidna––don't change.
- address testerAddr = 0x00a329c0648769a73afac7f9381e08fb43dbea70;
- address otherAddr = 0x67518339e369ab3d591d3569ab0a0d83b2ff5198;
- address ownerAddr = 0x00a329c0648769a73afac7f9381e08fb43dbea72;
- uint256 initial_totalSupply = 1000000000;
-
- constructor() public {
- /* config.yaml sets this contract's address to ownerAddr, so we
- need to initialize all the contract roles to this address so that calls
- from the contract pass funtion modifiers.*/
- initialize(
- "Test",
- "",
- "",
- 6,
- ownerAddr,
- ownerAddr,
- ownerAddr,
- ownerAddr
- );
- configureMinter(ownerAddr, initial_totalSupply);
- mint(testerAddr, initial_totalSupply / 2);
- require(balanceOf(testerAddr) == initial_totalSupply / 2);
- mint(otherAddr, initial_totalSupply / 2);
- require(balanceOf(otherAddr) == initial_totalSupply / 2);
- }
-
- function echidna_max_balance() public returns (bool) {
- // config.yaml specifies testerAddr is always the 'sender' address in transfers.
- return (balanceOf(testerAddr) <= initial_totalSupply / 2 &&
- balanceOf(otherAddr) >= initial_totalSupply / 2);
- }
-
- function echidna_no_burn_using_zero() public returns (bool) {
- return (balanceOf(0x0) == 0);
- }
-
- function echidna_self_transfer() public returns (bool) {
- uint256 balance = balanceOf(testerAddr);
- var b = transfer(testerAddr, balance);
- return (balanceOf(testerAddr) == balance && b);
- }
-
- function echidna_zero_transfer() public returns (bool) {
- return (transfer(otherAddr, 0));
- }
-
- function echidna_fixed_supply() public returns (bool) {
- return (totalSupply() == initial_totalSupply);
- }
-
- function echidna_self_approve_and_self_transferFrom()
- public
- returns (bool)
- {
- uint256 balance = balanceOf(testerAddr);
- approve(testerAddr, 0);
- approve(testerAddr, balance);
- return (transferFrom(testerAddr, testerAddr, balance));
- }
-
- function echidna_self_approve_and_transferFrom() public returns (bool) {
- uint256 balance = balanceOf(testerAddr);
- approve(testerAddr, 0);
- approve(testerAddr, balance);
- return (transferFrom(testerAddr, otherAddr, balance));
- }
-
- function echidna_multiple_approves() public returns (bool) {
- uint256 balance = balanceOf(testerAddr);
- approve(ownerAddr, balance);
- approve(ownerAddr, balance);
- return (allowed[testerAddr][ownerAddr] == balance);
- }
-}
diff --git a/flatten-generated-types.sh b/flatten-generated-types.sh
new file mode 100755
index 000000000..34a15ac5c
--- /dev/null
+++ b/flatten-generated-types.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR=@types/generated
+echo "Flattening $DIR"
+find $DIR -type f -mindepth 2 -exec mv {} $DIR \;;
+find $DIR -type d -mindepth 1 -empty -delete;
diff --git a/foundry.toml b/foundry.toml
new file mode 100644
index 000000000..196128c45
--- /dev/null
+++ b/foundry.toml
@@ -0,0 +1,42 @@
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+[profile.default]
+src = "contracts"
+out = "artifacts/foundry"
+cache_path = "cache/foundry"
+script = "scripts"
+optimizer_runs = 10000000
+libs = [
+ "lib",
+ "node_modules",
+]
+remappings = [
+ "forge-std/=lib/forge-std/src",
+ "@openzeppelin/=node_modules/@openzeppelin/",
+]
+fs_permissions = [
+ { access = "read-write", path = "blacklist.remote.json"},
+ { access = "read-write", path = "test.blacklist.remote.json"}
+] # https://book.getfoundry.sh/cheatcodes/fs
+extra-output-files = [
+ "bin",
+ "metadata"
+]
+
+[rpc_endpoints]
+testnet = "${TESTNET_RPC_URL}"
+mainnet = "${MAINNET_RPC_URL}"
diff --git a/hardhat.config.ts b/hardhat.config.ts
new file mode 100644
index 000000000..6ef8d4ced
--- /dev/null
+++ b/hardhat.config.ts
@@ -0,0 +1,103 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import dotenv from "dotenv";
+
+import type { HardhatUserConfig } from "hardhat/config";
+
+// Hardhat extensions
+import "@nomicfoundation/hardhat-chai-matchers";
+import "@nomicfoundation/hardhat-ethers";
+import "@nomicfoundation/hardhat-foundry";
+import "@nomiclabs/hardhat-truffle5";
+import "@typechain/hardhat";
+import "hardhat-contract-sizer";
+import "hardhat-gas-reporter";
+import "solidity-coverage";
+
+// Local hardhat scripts / tasks
+import "./scripts/hardhat/downloadBlacklistedAccounts";
+import "./scripts/hardhat/getContractCreationBlock";
+import "./scripts/hardhat/readValuesFromContract";
+import "./scripts/hardhat/validateAccountsToBlacklist";
+
+import "./scripts/hardhat/verifyOnChainBytecode";
+
+dotenv.config();
+
+// Defaults to 1.3 to be equivalent with Foundry
+const gasMultiplier = process.env.GAS_MULTIPLIER
+ ? parseFloat(process.env.GAS_MULTIPLIER) / 100
+ : 1.3;
+
+const hardhatConfig: HardhatUserConfig = {
+ solidity: {
+ version: "0.6.12",
+ settings: {
+ optimizer: {
+ enabled: true,
+ runs: parseInt(process.env.OPTIMIZER_RUNS || "10000000"),
+ },
+ },
+ },
+ paths: {
+ artifacts: "./artifacts/hardhat",
+ cache: "./cache/hardhat",
+ },
+ defaultNetwork: "hardhat",
+ networks: {
+ hardhat: {},
+ testnet: {
+ url: process.env.TESTNET_RPC_URL || "",
+ gasMultiplier,
+ },
+ mainnet: {
+ url: process.env.MAINNET_RPC_URL || "",
+ gasMultiplier,
+ },
+ },
+ typechain: {
+ outDir: "./@types/generated",
+ target: "truffle-v5",
+ alwaysGenerateOverloads: false,
+ externalArtifacts: ["build/contracts/**/*.json"],
+ dontOverrideCompile: false, // defaults to false
+ },
+ gasReporter: {
+ enabled: process.env.ENABLE_GAS_REPORTER == "true",
+ },
+ mocha: {
+ timeout: 60000, // prevents tests from failing when pc is under heavy load
+ grep: process.env.HARDHAT_TEST_GREP,
+ invert: process.env.HARDHAT_TEST_INVERT === "true",
+ reporter: "mocha-multi-reporters",
+ reporterOptions: {
+ reporterEnabled:
+ process.env.CI === "true" ? "spec, mocha-junit-reporter" : "spec",
+ mochaJunitReporterReporterOptions: {
+ mochaFile: "report/junit.xml",
+ },
+ },
+ },
+ contractSizer: {
+ strict: true,
+ except: ["contracts/test", "scripts/", "test/"],
+ },
+};
+
+export default hardhatConfig;
diff --git a/lib/forge-std b/lib/forge-std
new file mode 160000
index 000000000..4513bc206
--- /dev/null
+++ b/lib/forge-std
@@ -0,0 +1 @@
+Subproject commit 4513bc2063f23c57bee6558799584b518d387a39
diff --git a/migrations/1_initial_migration.js b/migrations/1_initial_migration.js
deleted file mode 100644
index 4d19593c3..000000000
--- a/migrations/1_initial_migration.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const Migrations = artifacts.require("Migrations");
-
-module.exports = async (deployer) => {
- await deployer.deploy(Migrations);
-};
diff --git a/migrations/2_deploy_v1.js b/migrations/2_deploy_v1.js
deleted file mode 100644
index f6d2865ca..000000000
--- a/migrations/2_deploy_v1.js
+++ /dev/null
@@ -1,98 +0,0 @@
-const fs = require("fs");
-const path = require("path");
-const some = require("lodash/some");
-
-const FiatTokenV1 = artifacts.require("FiatTokenV1");
-const FiatTokenProxy = artifacts.require("FiatTokenProxy");
-
-const THROWAWAY_ADDRESS = "0x0000000000000000000000000000000000000001";
-
-let proxyAdminAddress = "";
-let ownerAddress = "";
-let masterMinterAddress = "";
-let pauserAddress = "";
-let blacklisterAddress = "";
-
-// Read config file if it exists
-if (fs.existsSync(path.join(__dirname, "..", "config.js"))) {
- ({
- PROXY_ADMIN_ADDRESS: proxyAdminAddress,
- OWNER_ADDRESS: ownerAddress,
- MASTERMINTER_ADDRESS: masterMinterAddress,
- PAUSER_ADDRESS: pauserAddress,
- BLACKLISTER_ADDRESS: blacklisterAddress,
- } = require("../config.js"));
-}
-
-module.exports = async (deployer, network) => {
- if (some(["development", "coverage"], (v) => network.includes(v))) {
- // DO NOT USE THESE ADDRESSES IN PRODUCTION - these are the deterministic
- // addresses from ganache, so the private keys are well known and match the
- // values we use in the tests
- proxyAdminAddress = "0x2F560290FEF1B3Ada194b6aA9c40aa71f8e95598";
- ownerAddress = "0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d";
- masterMinterAddress = "0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9";
- pauserAddress = "0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E";
- blacklisterAddress = "0xd03ea8624C8C5987235048901fB614fDcA89b117";
- }
-
- console.log(`Proxy Admin: ${proxyAdminAddress}`);
- console.log(`Owner: ${ownerAddress}`);
- console.log(`Master Minter: ${masterMinterAddress}`);
- console.log(`Pauser: ${pauserAddress}`);
- console.log(`Blacklister: ${blacklisterAddress}`);
-
- if (
- !proxyAdminAddress ||
- !ownerAddress ||
- !masterMinterAddress ||
- !pauserAddress ||
- !blacklisterAddress
- ) {
- throw new Error(
- "PROXY_ADMIN_ADDRESS, OWNER_ADDRESS, MASTERMINTER_ADDRESS, PAUSER_ADDRESS, and BLACKLISTER_ADDRESS must be provided in config.js"
- );
- }
-
- console.log("Deploying implementation contract...");
- await deployer.deploy(FiatTokenV1);
- const fiatTokenV1 = await FiatTokenV1.deployed();
- console.log("Deployed implementation contract at", FiatTokenV1.address);
-
- console.log("Initializing implementation contract with dummy values...");
- await fiatTokenV1.initialize(
- "",
- "",
- "",
- 0,
- THROWAWAY_ADDRESS,
- THROWAWAY_ADDRESS,
- THROWAWAY_ADDRESS,
- THROWAWAY_ADDRESS
- );
-
- console.log("Deploying proxy contract...");
- await deployer.deploy(FiatTokenProxy, FiatTokenV1.address);
- const fiatTokenProxy = await FiatTokenProxy.deployed();
- console.log("Deployed proxy contract at", FiatTokenProxy.address);
-
- console.log("Reassigning proxy contract admin...");
- // need to change admin first, or the call to initialize won't work
- // since admin can only call methods in the proxy, and not forwarded methods
- await fiatTokenProxy.changeAdmin(proxyAdminAddress);
-
- console.log("Initializing proxy contract...");
- // Pretend that the proxy address is a FiatTokenV1 - this is fine because the
- // proxy will forward all the calls to the FiatTokenV1 impl
- const proxyAsV1 = await FiatTokenV1.at(FiatTokenProxy.address);
- await proxyAsV1.initialize(
- "USD//C",
- "USDC",
- "USD",
- 6,
- masterMinterAddress,
- pauserAddress,
- blacklisterAddress,
- ownerAddress
- );
-};
diff --git a/migrations/3_deploy_v2.js b/migrations/3_deploy_v2.js
deleted file mode 100644
index d63d011d0..000000000
--- a/migrations/3_deploy_v2.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const fs = require("fs");
-const path = require("path");
-const some = require("lodash/some");
-
-const FiatTokenV2 = artifacts.require("FiatTokenV2");
-const FiatTokenProxy = artifacts.require("FiatTokenProxy");
-const FiatTokenUtil = artifacts.require("FiatTokenUtil");
-
-const THROWAWAY_ADDRESS = "0x0000000000000000000000000000000000000001";
-
-let proxyContractAddress = "";
-
-// Read config file if it exists
-if (fs.existsSync(path.join(__dirname, "..", "config.js"))) {
- ({ PROXY_CONTRACT_ADDRESS: proxyContractAddress } = require("../config.js"));
-}
-
-module.exports = async (deployer, network) => {
- if (some(["development", "coverage"], (v) => network.includes(v))) {
- // DO NOT USE THIS ADDRESS IN PRODUCTION
- proxyContractAddress = (await FiatTokenProxy.deployed()).address;
- }
- proxyContractAddress =
- proxyContractAddress || (await FiatTokenProxy.deployed()).address;
-
- console.log(`FiatTokenProxy: ${proxyContractAddress}`);
-
- console.log("Deploying FiatTokenV2 implementation contract...");
- await deployer.deploy(FiatTokenV2);
-
- const fiatTokenV2 = await FiatTokenV2.deployed();
- console.log("Deployed FiatTokenV2 at", fiatTokenV2.address);
- console.log(
- "Initializing FiatTokenV2 implementation contract with dummy values..."
- );
- await fiatTokenV2.initialize(
- "",
- "",
- "",
- 0,
- THROWAWAY_ADDRESS,
- THROWAWAY_ADDRESS,
- THROWAWAY_ADDRESS,
- THROWAWAY_ADDRESS
- );
- await fiatTokenV2.initializeV2("");
-
- console.log("Deploying FiatTokenUtil contract...");
- const fiatTokenUtil = await deployer.deploy(
- FiatTokenUtil,
- proxyContractAddress
- );
- console.log("Deployed FiatTokenUtil at", fiatTokenUtil.address);
-};
diff --git a/migrations/4_deploy_v2_upgrader.js b/migrations/4_deploy_v2_upgrader.js
deleted file mode 100644
index 8bace174d..000000000
--- a/migrations/4_deploy_v2_upgrader.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const fs = require("fs");
-const path = require("path");
-const some = require("lodash/some");
-
-const FiatTokenV2 = artifacts.require("FiatTokenV2");
-const FiatTokenProxy = artifacts.require("FiatTokenProxy");
-const V2Upgrader = artifacts.require("V2Upgrader");
-
-let proxyAdminAddress = "";
-let proxyContractAddress = "";
-
-// Read config file if it exists
-if (fs.existsSync(path.join(__dirname, "..", "config.js"))) {
- ({
- PROXY_ADMIN_ADDRESS: proxyAdminAddress,
- PROXY_CONTRACT_ADDRESS: proxyContractAddress,
- } = require("../config.js"));
-}
-
-module.exports = async (deployer, network) => {
- if (some(["development", "coverage"], (v) => network.includes(v))) {
- // DO NOT USE THIS ADDRESS IN PRODUCTION
- proxyAdminAddress = "0x2F560290FEF1B3Ada194b6aA9c40aa71f8e95598";
- proxyContractAddress = (await FiatTokenProxy.deployed()).address;
- }
- proxyContractAddress =
- proxyContractAddress || (await FiatTokenProxy.deployed()).address;
-
- const fiatTokenV2 = await FiatTokenV2.deployed();
-
- console.log(`Proxy Admin: ${proxyAdminAddress}`);
- console.log(`FiatTokenProxy: ${proxyContractAddress}`);
- console.log(`FiatTokenV2: ${fiatTokenV2.address}`);
-
- if (!proxyAdminAddress) {
- throw new Error("PROXY_ADMIN_ADDRESS must be provided in config.js");
- }
-
- console.log("Deploying V2Upgrader contract...");
-
- const v2Upgrader = await deployer.deploy(
- V2Upgrader,
- proxyContractAddress,
- fiatTokenV2.address,
- proxyAdminAddress,
- "USD Coin"
- );
-
- console.log(`>>>>>>> Deployed V2Upgrader at ${v2Upgrader.address} <<<<<<<`);
-};
diff --git a/package.json b/package.json
index a58680b0f..c272a583d 100644
--- a/package.json
+++ b/package.json
@@ -1,77 +1,103 @@
{
- "name": "centre-tokens",
+ "name": "stablecoin-evm",
"version": "1.0.0",
- "description": "Fiat and non-fiat tokens part of the CENTRE network.",
- "main": "truffle-config.js",
+ "description": "Circle's Stablecoin Smart Contracts on EVM-compatible blockchains",
"directories": {
"test": "test"
},
"scripts": {
- "setup": "git config core.hooksPath .githooks",
- "compile": "truffle compile",
- "typechain": "yarn compile && rm -rf './@types/generated' && typechain --target=truffle-v5 --outDir './@types/generated' 'build/contracts/**/*.json'",
- "typecheck": "tsc -p . --noEmit",
+ "compile": "hardhat compile && forge build && ./flatten-generated-types.sh",
+ "contract-size": "hardhat size-contracts",
+ "coverage": "hardhat coverage",
+ "forge:simulate": "forge script -vv --gas-estimate-multiplier $(dotenv -p GAS_MULTIPLIER)",
+ "forge:broadcast": "yarn forge:simulate --broadcast --slow",
+ "forge:resume": "yarn forge:broadcast --resume",
+ "forge:broadcastAndVerify": "yarn forge:broadcast --verify --etherscan-api-key $(dotenv -p ETHERSCAN_KEY)",
+ "forge:verify": "yarn forge:simulate --verify --resume --etherscan-api-key $(dotenv -p ETHERSCAN_KEY) --private-key $(dotenv -p DEPLOYER_PRIVATE_KEY)",
+ "fmt:base": "prettier './**/*.sol' './**/*.js' './**/*.ts' './**/*.json' './**/*.md'",
+ "fmt:check": "yarn fmt:base --check",
+ "fmt": "yarn fmt:base --write",
+ "gas-report": "hardhat test test/misc/gas.ts",
"lint": "eslint --ext '.js,.ts' './**/*.{j,t}s'",
- "fmt": "prettier --write './**/*.sol' './**/*.js' './**/*.ts' './**/*.json' './**/*.md'",
- "ganache": "ganache-cli --accounts=15 --deterministic --defaultBalanceEther=1000000 --quiet",
- "test": "truffle test",
- "coverage": "truffle run coverage",
+ "postinstall": "bash setup.sh && husky install",
+ "precommit": "yarn fmt && yarn static-check",
"solhint": "solhint 'contracts/**/*.sol'",
- "precommit": "yarn typechain && yarn fmt && yarn typecheck && yarn lint && yarn solhint",
- "slither": "slither --solc-disable-warnings --disable-color --exclude-dependencies .",
- "migrate": "truffle migrate --interactive"
+ "static-check": "yarn hardhat typechain && yarn typecheck && yarn lint && yarn fmt:check && yarn solhint",
+ "test": "hardhat test",
+ "typecheck": "tsc -p . --noEmit"
},
"repository": {
"type": "git",
- "url": "git+https://github.com/centrehq/centre-tokens.git"
+ "url": "git+https://github.com/circlefin/stablecoin-evm.git"
},
"keywords": [],
"author": "",
- "license": "MIT",
+ "license": "Apache-2.0",
"bugs": {
- "url": "https://github.com/centrehq/centre-tokens/issues"
+ "url": "https://github.com/circlefin/stablecoin-evm/issues"
},
- "homepage": "https://github.com/centrehq/centre-tokens#readme",
- "dependencies": {},
+ "homepage": "https://github.com/circlefin/stablecoin-evm#readme",
"devDependencies": {
- "@openzeppelin/contracts": "^3.1.0",
- "@truffle/hdwallet-provider": "^1.0.39",
- "@typechain/truffle-v5": "^2.0.2",
- "@types/chai": "^4.2.11",
- "@types/lodash": "^4.14.158",
- "@types/mocha": "^8.0.0",
- "@typescript-eslint/eslint-plugin": "^3.7.0",
- "@typescript-eslint/parser": "^3.7.0",
- "chai": "^4.2.0",
- "diff": "^4.0.2",
- "eslint": "^7.5.0",
- "eslint-config-prettier": "^6.11.0",
- "eslint-config-standard": "^14.1.1",
- "eslint-plugin-import": "^2.22.0",
- "eslint-plugin-node": "^11.1.0",
- "eslint-plugin-prettier": "^3.1.4",
- "eslint-plugin-promise": "^4.2.1",
- "eslint-plugin-standard": "^4.0.1",
- "ethereumjs-abi": "^0.6.8",
- "ethereumjs-tx": "^2.1.2",
- "ethereumjs-util": "^7.0.3",
- "ganache-cli": "^6.9.1",
- "googleapis": "^55.0.0",
- "lodash": "^4.17.19",
+ "@nomicfoundation/hardhat-chai-matchers": "2.0.2",
+ "@nomicfoundation/hardhat-ethers": "3.0.4",
+ "@nomicfoundation/hardhat-foundry": "1.1.1",
+ "@nomicfoundation/hardhat-network-helpers": "1.0.8",
+ "@nomiclabs/hardhat-truffle5": "2.0.7",
+ "@nomiclabs/hardhat-web3": "2.0.0",
+ "@openzeppelin/contracts": "3.4.2",
+ "@typechain/ethers-v6": "0.4.3",
+ "@typechain/hardhat": "9.0.0",
+ "@typechain/truffle-v5": "8.0.6",
+ "@types/chai": "4.3.5",
+ "@types/ethereumjs-abi": "0.6.3",
+ "@types/lodash": "4.14.195",
+ "@types/mocha": "10.0.1",
+ "@types/node": "20.5.1",
+ "@types/sinon": "17.0.3",
+ "@typescript-eslint/eslint-plugin": "3.10.1",
+ "@typescript-eslint/parser": "3.10.1",
+ "assert-diff": "1.2.6",
+ "bs58": "5.0.0",
+ "cbor": "9.0.2",
+ "chai": "4.3.7",
+ "dotenv": "16.4.1",
+ "dotenv-cli": "7.3.0",
+ "eslint": "7.32.0",
+ "eslint-config-prettier": "6.15.0",
+ "eslint-config-standard": "14.1.1",
+ "eslint-plugin-import": "2.27.5",
+ "eslint-plugin-node": "11.1.0",
+ "eslint-plugin-prettier": "3.4.1",
+ "eslint-plugin-promise": "4.3.1",
+ "eslint-plugin-standard": "4.1.0",
+ "ethereumjs-abi": "0.6.8",
+ "ethereumjs-util": "7.1.5",
+ "ethers": "6.11.1",
+ "hardhat": "2.19.4",
+ "hardhat-contract-sizer": "2.10.0",
+ "hardhat-gas-reporter": "1.0.10",
+ "husky": "8.0.3",
+ "ipfs-only-hash": "4.0.0",
+ "lodash": "4.17.21",
+ "mocha-junit-reporter": "2.2.1",
+ "mocha-multi-reporters": "1.5.1",
"prettier": "2.0.5",
"prettier-plugin-solidity": "1.0.0-alpha.54",
- "q": "^1.5.1",
+ "q": "1.5.1",
+ "sinon": "19.0.2",
"solc": "0.6.12",
- "solhint": "^3.1.0",
- "solidity-coverage": "^0.7.9",
- "truffle": "^5.1.35",
- "ts-node": "^8.10.2",
- "typechain": "^2.0.0",
- "typescript": "^3.9.7",
- "web3": "^1.2.11"
+ "solhint": "3.4.1",
+ "solidity-coverage": "0.8.9",
+ "ts-node": "10.9.1",
+ "typechain": "8.3.1",
+ "typescript": "5.1.6",
+ "web3": "1.10.1"
+ },
+ "resolutions": {
+ "hardhat-gas-reporter/**/flat": "5.0.2"
},
"engines": {
- "node": ">= 12.0.0",
- "yarn": ">= 1.21.1"
+ "node": "20.9.0",
+ "yarn": "1.22.19"
}
}
diff --git a/scripts/deploy/DeployImpl.sol b/scripts/deploy/DeployImpl.sol
new file mode 100644
index 000000000..3adced057
--- /dev/null
+++ b/scripts/deploy/DeployImpl.sol
@@ -0,0 +1,110 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import { FiatTokenV2_2 } from "../../contracts/v2/FiatTokenV2_2.sol";
+import {
+ FiatTokenCeloV2_2
+} from "../../contracts/v2/celo/FiatTokenCeloV2_2.sol";
+
+/**
+ * @notice A utility contract that exposes a re-useable getOrDeployImpl function.
+ */
+contract DeployImpl {
+ address private immutable THROWAWAY_ADDRESS = address(1);
+
+ /**
+ * @notice helper function that either
+ * 1) deploys the implementation contract if the input is the zero address, or
+ * 2) loads an instance of an existing contract when input is not the zero address.
+ *
+ * @param impl configured of the implementation contract, where address(0) represents a new instance should be deployed
+ * @return FiatTokenV2_2 newly deployed or loaded instance
+ */
+ function getOrDeployImpl(address impl) internal returns (FiatTokenV2_2) {
+ FiatTokenV2_2 fiatTokenV2_2;
+
+ if (impl == address(0)) {
+ fiatTokenV2_2 = new FiatTokenV2_2();
+
+ // Initializing the implementation contract with dummy values here prevents
+ // the contract from being reinitialized later on with different values.
+ // Dummy values can be used here as the proxy contract will store the actual values
+ // for the deployed token.
+ fiatTokenV2_2.initialize(
+ "",
+ "",
+ "",
+ 0,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS
+ );
+ fiatTokenV2_2.initializeV2("");
+ fiatTokenV2_2.initializeV2_1(THROWAWAY_ADDRESS);
+ fiatTokenV2_2.initializeV2_2(new address[](0), "");
+ } else {
+ fiatTokenV2_2 = FiatTokenV2_2(impl);
+ }
+
+ return fiatTokenV2_2;
+ }
+
+ /**
+ * @notice helper function that either
+ * 1) deploys the implementation contract if the input is the zero address, or
+ * 2) loads an instance of an existing contract when input is not the zero address.
+ *
+ * @param impl configured of the implementation contract, where address(0) represents a new instance should be deployed
+ * @return FiatTokenCeloV2_2 newly deployed or loaded instance
+ */
+ function getOrDeployImplCelo(address impl)
+ internal
+ returns (FiatTokenCeloV2_2)
+ {
+ FiatTokenCeloV2_2 fiatTokenCeloV2_2;
+
+ if (impl == address(0)) {
+ fiatTokenCeloV2_2 = new FiatTokenCeloV2_2();
+
+ // Initializing the implementation contract with dummy values here prevents
+ // the contract from being reinitialized later on with different values.
+ // Dummy values can be used here as the proxy contract will store the actual values
+ // for the deployed token.
+ fiatTokenCeloV2_2.initialize(
+ "",
+ "",
+ "",
+ 0,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS,
+ THROWAWAY_ADDRESS
+ );
+ fiatTokenCeloV2_2.initializeV2("");
+ fiatTokenCeloV2_2.initializeV2_1(THROWAWAY_ADDRESS);
+ fiatTokenCeloV2_2.initializeV2_2(new address[](0), "");
+ } else {
+ fiatTokenCeloV2_2 = FiatTokenCeloV2_2(impl);
+ }
+
+ return fiatTokenCeloV2_2;
+ }
+}
diff --git a/scripts/deploy/ScriptUtils.sol b/scripts/deploy/ScriptUtils.sol
new file mode 100644
index 000000000..2927e4980
--- /dev/null
+++ b/scripts/deploy/ScriptUtils.sol
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376
+
+import { Script } from "forge-std/Script.sol";
+
+/**
+ * Shared utilities for scripts. It inherits the Script contract in order
+ * to access vm cheatcodes.
+ */
+contract ScriptUtils is Script {
+ /**
+ * @notice helper function that loads local json
+ */
+ function _loadAccountsToBlacklist(string memory blacklistFileName)
+ internal
+ view
+ returns (address[] memory)
+ {
+ string memory json = vm.readFile(blacklistFileName);
+ return vm.parseJsonAddressArray(json, "");
+ }
+}
diff --git a/scripts/deploy/celo/deploy-fee-adapter.s.sol b/scripts/deploy/celo/deploy-fee-adapter.s.sol
new file mode 100644
index 000000000..471e070df
--- /dev/null
+++ b/scripts/deploy/celo/deploy-fee-adapter.s.sol
@@ -0,0 +1,113 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import "forge-std/console.sol"; // solhint-disable no-global-import, no-console
+import { Script } from "forge-std/Script.sol";
+import {
+ FiatTokenFeeAdapterProxy
+} from "../../../contracts/v2/celo/FiatTokenFeeAdapterProxy.sol";
+import {
+ FiatTokenFeeAdapterV1
+} from "../../../contracts/v2/celo/FiatTokenFeeAdapterV1.sol";
+
+/**
+ * A utility script to directly deploy Celo-specific fee adapter contract with the latest implementation.
+ * The fee adapter contract sits behind a fee adapter proxy, which is also deployed in this script.
+ */
+contract DeployFeeAdapter is Script {
+ address private adapterProxyAdminAddress;
+ address payable private fiatTokenProxyAddress;
+
+ uint8 private feeAdapterDecimals;
+
+ uint256 private deployerPrivateKey;
+
+ /**
+ * @notice initialize variables from environment
+ */
+ function setUp() public {
+ adapterProxyAdminAddress = vm.envAddress(
+ "FEE_ADAPTER_PROXY_ADMIN_ADDRESS"
+ );
+ fiatTokenProxyAddress = payable(
+ vm.envAddress("FIAT_TOKEN_CELO_PROXY_ADDRESS")
+ );
+
+ feeAdapterDecimals = uint8(vm.envUint("FEE_ADAPTER_DECIMALS"));
+
+ deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
+
+ console.log(
+ "FEE_ADAPTER_PROXY_ADMIN_ADDRESS: '%s'",
+ adapterProxyAdminAddress
+ );
+ console.log(
+ "FIAT_TOKEN_CELO_PROXY_ADDRESS: '%s'",
+ fiatTokenProxyAddress
+ );
+ console.log("FEE_ADAPTER_DECIMALS: '%s'", feeAdapterDecimals);
+ }
+
+ /**
+ * @dev For testing only: splitting deploy logic into an internal function to expose for testing
+ */
+ function _deploy()
+ internal
+ returns (FiatTokenFeeAdapterV1, FiatTokenFeeAdapterProxy)
+ {
+ vm.startBroadcast(deployerPrivateKey);
+
+ // Deploy the implementation of the fee adapter
+ FiatTokenFeeAdapterV1 feeAdapter = new FiatTokenFeeAdapterV1();
+ // Initialize with some values, we only rely on the implementation
+ // deployment for delegatecall logic, not for actual state storage.
+ feeAdapter.initializeV1(fiatTokenProxyAddress, feeAdapterDecimals);
+
+ // Deploy the proxy contract for the fee adapter
+ FiatTokenFeeAdapterProxy feeAdapterProxy = new FiatTokenFeeAdapterProxy(
+ address(feeAdapter)
+ );
+
+ // Reassign the admin on the adapter proxy, as proxy admins aren't allowed
+ // to call the fallback (delegate) functions. The call to initializeV1 won't
+ // work if this isn't done.
+ feeAdapterProxy.changeAdmin(adapterProxyAdminAddress);
+
+ // Initialize the adapter proxy with proper values.
+ FiatTokenFeeAdapterV1 proxyAsV1 = FiatTokenFeeAdapterV1(
+ address(feeAdapterProxy)
+ );
+ proxyAsV1.initializeV1(fiatTokenProxyAddress, feeAdapterDecimals);
+
+ vm.stopBroadcast();
+
+ return (feeAdapter, feeAdapterProxy);
+ }
+
+ /**
+ * @notice main function that will be run by forge
+ */
+ function run()
+ external
+ returns (FiatTokenFeeAdapterV1, FiatTokenFeeAdapterProxy)
+ {
+ return _deploy();
+ }
+}
diff --git a/scripts/deploy/celo/deploy-fiat-token-celo.s.sol b/scripts/deploy/celo/deploy-fiat-token-celo.s.sol
new file mode 100644
index 000000000..81da66aa9
--- /dev/null
+++ b/scripts/deploy/celo/deploy-fiat-token-celo.s.sol
@@ -0,0 +1,176 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import "forge-std/console.sol"; // solhint-disable no-global-import, no-console
+import { Script } from "forge-std/Script.sol";
+import { DeployImpl } from "../DeployImpl.sol";
+import { FiatTokenProxy } from "../../../contracts/v1/FiatTokenProxy.sol";
+import {
+ FiatTokenCeloV2_2
+} from "../../../contracts/v2/celo/FiatTokenCeloV2_2.sol";
+import { MasterMinter } from "../../../contracts/minting/MasterMinter.sol";
+
+/**
+ * A utility script to directly deploy Fiat Token contract with the latest implementation
+ *
+ * @dev The proxy needs to be deployed before the master minter; the proxy cannot
+ * be initialized until the master minter is deployed.
+ */
+contract DeployFiatTokenCelo is Script, DeployImpl {
+ address private immutable THROWAWAY_ADDRESS = address(1);
+
+ address private impl;
+ address private masterMinterOwner;
+ address private proxyAdmin;
+ address private owner;
+ address private pauser;
+ address private blacklister;
+ address private lostAndFound;
+
+ string private tokenName;
+ string private tokenSymbol;
+ string private tokenCurrency;
+ uint8 private tokenDecimals;
+
+ uint256 private deployerPrivateKey;
+
+ /**
+ * @notice initialize variables from environment
+ */
+ function setUp() public {
+ tokenName = vm.envString("TOKEN_NAME");
+ tokenSymbol = vm.envString("TOKEN_SYMBOL");
+ tokenCurrency = vm.envString("TOKEN_CURRENCY");
+ tokenDecimals = uint8(vm.envUint("TOKEN_DECIMALS"));
+
+ impl = vm.envOr("FIAT_TOKEN_CELO_IMPLEMENTATION_ADDRESS", address(0));
+ proxyAdmin = vm.envAddress("PROXY_ADMIN_ADDRESS");
+ masterMinterOwner = vm.envAddress("MASTER_MINTER_OWNER_ADDRESS");
+ owner = vm.envAddress("OWNER_ADDRESS");
+
+ // Pauser, blacklister, and lost and found addresses can default to owner address
+ pauser = vm.envOr("PAUSER_ADDRESS", owner);
+ blacklister = vm.envOr("BLACKLISTER_ADDRESS", owner);
+ lostAndFound = vm.envOr("LOST_AND_FOUND_ADDRESS", owner);
+
+ deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
+
+ console.log("TOKEN_NAME: '%s'", tokenName);
+ console.log("TOKEN_SYMBOL: '%s'", tokenSymbol);
+ console.log("TOKEN_CURRENCY: '%s'", tokenCurrency);
+ console.log("TOKEN_DECIMALS: '%s'", tokenDecimals);
+ console.log("FIAT_TOKEN_IMPLEMENTATION_ADDRESS: '%s'", impl);
+ console.log("PROXY_ADMIN_ADDRESS: '%s'", proxyAdmin);
+ console.log("MASTER_MINTER_OWNER_ADDRESS: '%s'", masterMinterOwner);
+ console.log("OWNER_ADDRESS: '%s'", owner);
+ console.log("PAUSER_ADDRESS: '%s'", pauser);
+ console.log("BLACKLISTER_ADDRESS: '%s'", blacklister);
+ console.log("LOST_AND_FOUND_ADDRESS: '%s'", lostAndFound);
+ }
+
+ /**
+ * @dev For testing only: splitting deploy logic into an internal function to expose for testing
+ */
+ function _deploy(address _impl)
+ internal
+ returns (
+ FiatTokenCeloV2_2,
+ MasterMinter,
+ FiatTokenProxy
+ )
+ {
+ vm.startBroadcast(deployerPrivateKey);
+
+ // If there is an existing implementation contract,
+ // we can simply point the newly deployed proxy contract to it.
+ // Otherwise, deploy the latest implementation contract code to the network.
+ FiatTokenCeloV2_2 fiatTokenCeloV2_2 = getOrDeployImplCelo(_impl);
+
+ FiatTokenProxy proxy = new FiatTokenProxy(address(fiatTokenCeloV2_2));
+
+ // Now that the proxy contract has been deployed, we can deploy the master minter.
+ MasterMinter masterMinter = new MasterMinter(address(proxy));
+
+ // Change the master minter to be owned by the master minter owner
+ masterMinter.transferOwnership(masterMinterOwner);
+
+ // Now that the master minter is set up, we can go back to setting up the proxy and
+ // implementation contracts.
+ // Need to change admin first, or the call to initialize won't work
+ // since admin can only call methods in the proxy, and not forwarded methods
+ proxy.changeAdmin(proxyAdmin);
+
+ // Do the initial (V1) initialization.
+ // Note that this takes in the master minter contract's address as the master minter.
+ // The master minter contract's owner is a separate address.
+ FiatTokenCeloV2_2 proxyAsV2_2 = FiatTokenCeloV2_2(address(proxy));
+ proxyAsV2_2.initialize(
+ tokenName,
+ tokenSymbol,
+ tokenCurrency,
+ tokenDecimals,
+ address(masterMinter),
+ pauser,
+ blacklister,
+ owner
+ );
+
+ // Do the V2 initialization
+ proxyAsV2_2.initializeV2(tokenName);
+
+ // Do the V2_1 initialization
+ proxyAsV2_2.initializeV2_1(lostAndFound);
+
+ // Do the V2_2 initialization
+ proxyAsV2_2.initializeV2_2(new address[](0), tokenSymbol);
+
+ vm.stopBroadcast();
+
+ return (fiatTokenCeloV2_2, masterMinter, proxy);
+ }
+
+ /**
+ * @dev For testing only: Helper function that runs deploy script with a specific implementation address
+ */
+ function deploy(address _impl)
+ external
+ returns (
+ FiatTokenCeloV2_2,
+ MasterMinter,
+ FiatTokenProxy
+ )
+ {
+ return _deploy(_impl);
+ }
+
+ /**
+ * @notice main function that will be run by forge
+ */
+ function run()
+ external
+ returns (
+ FiatTokenCeloV2_2,
+ MasterMinter,
+ FiatTokenProxy
+ )
+ {
+ return _deploy(impl);
+ }
+}
diff --git a/scripts/deploy/deploy-fiat-token.s.sol b/scripts/deploy/deploy-fiat-token.s.sol
new file mode 100644
index 000000000..499e508e3
--- /dev/null
+++ b/scripts/deploy/deploy-fiat-token.s.sol
@@ -0,0 +1,171 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import "forge-std/console.sol"; // solhint-disable no-global-import, no-console
+import { Script } from "forge-std/Script.sol";
+import { DeployImpl } from "./DeployImpl.sol";
+import { FiatTokenProxy } from "../../contracts/v1/FiatTokenProxy.sol";
+import { FiatTokenV2_2 } from "../../contracts/v2/FiatTokenV2_2.sol";
+import { MasterMinter } from "../../contracts/minting/MasterMinter.sol";
+
+/**
+ * A utility script to directly deploy Fiat Token contract with the latest implementation
+ *
+ * @dev The proxy needs to be deployed before the master minter; the proxy cannot
+ * be initialized until the master minter is deployed.
+ */
+contract DeployFiatToken is Script, DeployImpl {
+ address private immutable THROWAWAY_ADDRESS = address(1);
+
+ address private impl;
+ address private masterMinterOwner;
+ address private proxyAdmin;
+ address private owner;
+ address private pauser;
+ address private blacklister;
+
+ string private tokenName;
+ string private tokenSymbol;
+ string private tokenCurrency;
+ uint8 private tokenDecimals;
+
+ uint256 private deployerPrivateKey;
+
+ /**
+ * @notice initialize variables from environment
+ */
+ function setUp() public {
+ tokenName = vm.envString("TOKEN_NAME");
+ tokenSymbol = vm.envString("TOKEN_SYMBOL");
+ tokenCurrency = vm.envString("TOKEN_CURRENCY");
+ tokenDecimals = uint8(vm.envUint("TOKEN_DECIMALS"));
+
+ impl = vm.envOr("FIAT_TOKEN_IMPLEMENTATION_ADDRESS", address(0));
+ proxyAdmin = vm.envAddress("PROXY_ADMIN_ADDRESS");
+ masterMinterOwner = vm.envAddress("MASTER_MINTER_OWNER_ADDRESS");
+ owner = vm.envAddress("OWNER_ADDRESS");
+
+ // Pauser and blacklister addresses can default to owner address
+ pauser = vm.envOr("PAUSER_ADDRESS", owner);
+ blacklister = vm.envOr("BLACKLISTER_ADDRESS", owner);
+
+ deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
+
+ console.log("TOKEN_NAME: '%s'", tokenName);
+ console.log("TOKEN_SYMBOL: '%s'", tokenSymbol);
+ console.log("TOKEN_CURRENCY: '%s'", tokenCurrency);
+ console.log("TOKEN_DECIMALS: '%s'", tokenDecimals);
+ console.log("FIAT_TOKEN_IMPLEMENTATION_ADDRESS: '%s'", impl);
+ console.log("PROXY_ADMIN_ADDRESS: '%s'", proxyAdmin);
+ console.log("MASTER_MINTER_OWNER_ADDRESS: '%s'", masterMinterOwner);
+ console.log("OWNER_ADDRESS: '%s'", owner);
+ console.log("PAUSER_ADDRESS: '%s'", pauser);
+ console.log("BLACKLISTER_ADDRESS: '%s'", blacklister);
+ }
+
+ /**
+ * @dev For testing only: splitting deploy logic into an internal function to expose for testing
+ */
+ function _deploy(address _impl)
+ internal
+ returns (
+ FiatTokenV2_2,
+ MasterMinter,
+ FiatTokenProxy
+ )
+ {
+ vm.startBroadcast(deployerPrivateKey);
+
+ // If there is an existing implementation contract,
+ // we can simply point the newly deployed proxy contract to it.
+ // Otherwise, deploy the latest implementation contract code to the network.
+ FiatTokenV2_2 fiatTokenV2_2 = getOrDeployImpl(_impl);
+
+ FiatTokenProxy proxy = new FiatTokenProxy(address(fiatTokenV2_2));
+
+ // Now that the proxy contract has been deployed, we can deploy the master minter.
+ MasterMinter masterMinter = new MasterMinter(address(proxy));
+
+ // Change the master minter to be owned by the master minter owner
+ masterMinter.transferOwnership(masterMinterOwner);
+
+ // Now that the master minter is set up, we can go back to setting up the proxy and
+ // implementation contracts.
+ // Need to change admin first, or the call to initialize won't work
+ // since admin can only call methods in the proxy, and not forwarded methods
+ proxy.changeAdmin(proxyAdmin);
+
+ // Do the initial (V1) initialization.
+ // Note that this takes in the master minter contract's address as the master minter.
+ // The master minter contract's owner is a separate address.
+ FiatTokenV2_2 proxyAsV2_2 = FiatTokenV2_2(address(proxy));
+ proxyAsV2_2.initialize(
+ tokenName,
+ tokenSymbol,
+ tokenCurrency,
+ tokenDecimals,
+ address(masterMinter),
+ pauser,
+ blacklister,
+ owner
+ );
+
+ // Do the V2 initialization
+ proxyAsV2_2.initializeV2(tokenName);
+
+ // Do the V2_1 initialization
+ proxyAsV2_2.initializeV2_1(owner);
+
+ // Do the V2_2 initialization
+ proxyAsV2_2.initializeV2_2(new address[](0), tokenSymbol);
+
+ vm.stopBroadcast();
+
+ return (fiatTokenV2_2, masterMinter, proxy);
+ }
+
+ /**
+ * @dev For testing only: Helper function that runs deploy script with a specific implementation address
+ */
+ function deploy(address _impl)
+ external
+ returns (
+ FiatTokenV2_2,
+ MasterMinter,
+ FiatTokenProxy
+ )
+ {
+ return _deploy(_impl);
+ }
+
+ /**
+ * @notice main function that will be run by forge
+ */
+ function run()
+ external
+ returns (
+ FiatTokenV2_2,
+ MasterMinter,
+ FiatTokenProxy
+ )
+ {
+ return _deploy(impl);
+ }
+}
diff --git a/scripts/deploy/deploy-impl-and-upgrader.s.sol b/scripts/deploy/deploy-impl-and-upgrader.s.sol
new file mode 100644
index 000000000..57ae0273f
--- /dev/null
+++ b/scripts/deploy/deploy-impl-and-upgrader.s.sol
@@ -0,0 +1,112 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import "forge-std/console.sol"; // solhint-disable no-global-import, no-console
+import { Script } from "forge-std/Script.sol";
+import { ScriptUtils } from "./ScriptUtils.sol";
+import { DeployImpl } from "./DeployImpl.sol";
+import { FiatTokenProxy } from "../../contracts/v1/FiatTokenProxy.sol";
+import { FiatTokenV2_2 } from "../../contracts/v2/FiatTokenV2_2.sol";
+import { V2_2Upgrader } from "../../contracts/v2/upgrader/V2_2Upgrader.sol";
+
+/**
+ * A utility script to deploy the latest fiat token implementation and
+ * an upgrader contract that updates fiat token use the latest implementation
+ */
+contract DeployImplAndUpgrader is Script, DeployImpl, ScriptUtils {
+ string private newTokenSymbol;
+ string private blacklistFileName;
+ address private impl;
+ address payable private proxyContractAddress;
+ address private proxyAdmin;
+ address private lostAndFound;
+ address[] private accountsToBlacklist;
+
+ uint256 private deployerPrivateKey;
+
+ /**
+ * @notice initialize variables from environment
+ */
+ function setUp() public {
+ impl = vm.envOr("FIAT_TOKEN_IMPLEMENTATION_ADDRESS", address(0));
+
+ newTokenSymbol = vm.envString("TOKEN_SYMBOL");
+ proxyContractAddress = payable(
+ vm.envAddress("FIAT_TOKEN_PROXY_ADDRESS")
+ );
+ proxyAdmin = vm.envAddress("PROXY_ADMIN_ADDRESS");
+ lostAndFound = vm.envOr(
+ "LOST_AND_FOUND_ADDRESS",
+ vm.envAddress("OWNER_ADDRESS")
+ );
+
+ blacklistFileName = vm.envString("BLACKLIST_FILE_NAME");
+ accountsToBlacklist = _loadAccountsToBlacklist(blacklistFileName);
+
+ deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
+
+ console.log("FIAT_TOKEN_IMPLEMENTATION_ADDRESS: '%s'", impl);
+ console.log("TOKEN_SYMBOL: '%s'", newTokenSymbol);
+ console.log("FIAT_TOKEN_PROXY_ADDRESS: '%s'", proxyContractAddress);
+ console.log("PROXY_ADMIN_ADDRESS: '%s'", proxyAdmin);
+ console.log("LOST_AND_FOUND_ADDRESS: '%s'", lostAndFound);
+ console.log("BLACKLIST_FILE_NAME: '%s'", blacklistFileName);
+ }
+
+ /**
+ * @dev For testing only: splitting deploy logic into an internal function to expose for testing
+ */
+ function _deploy(address _impl)
+ internal
+ returns (FiatTokenV2_2, V2_2Upgrader)
+ {
+ vm.startBroadcast(deployerPrivateKey);
+
+ FiatTokenV2_2 fiatTokenV2_2 = getOrDeployImpl(_impl);
+
+ V2_2Upgrader v2_2Upgrader = new V2_2Upgrader(
+ FiatTokenProxy(proxyContractAddress),
+ fiatTokenV2_2,
+ proxyAdmin,
+ accountsToBlacklist,
+ newTokenSymbol
+ );
+
+ vm.stopBroadcast();
+ return (fiatTokenV2_2, v2_2Upgrader);
+ }
+
+ /**
+ * @dev For testing only: Helper function that runs deploy script with a specific implementation address
+ */
+ function deploy(address _impl)
+ external
+ returns (FiatTokenV2_2, V2_2Upgrader)
+ {
+ return _deploy(_impl);
+ }
+
+ /**
+ * @notice main function that will be run by forge
+ */
+ function run() external returns (FiatTokenV2_2, V2_2Upgrader) {
+ return _deploy(impl);
+ }
+}
diff --git a/scripts/deploy/deploy-master-minter.s.sol b/scripts/deploy/deploy-master-minter.s.sol
new file mode 100644
index 000000000..9fffade76
--- /dev/null
+++ b/scripts/deploy/deploy-master-minter.s.sol
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+
+import "forge-std/console.sol"; // solhint-disable no-global-import, no-console
+import { Script } from "forge-std/Script.sol";
+import { MasterMinter } from "../../contracts/minting/MasterMinter.sol";
+
+/**
+ * A utility script to deploy a standslone MasterMinter contract
+ */
+contract DeployMasterMinter is Script {
+ address payable private proxyContractAddress;
+ address private masterMinterOwner;
+ uint256 private deployerPrivateKey;
+
+ /**
+ * @notice initialize variables from environment
+ */
+ function setUp() public {
+ proxyContractAddress = payable(
+ vm.envAddress("FIAT_TOKEN_PROXY_ADDRESS")
+ );
+ masterMinterOwner = vm.envAddress("MASTER_MINTER_OWNER_ADDRESS");
+
+ deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
+
+ console.log("FIAT_TOKEN_PROXY_ADDRESS: '%s'", proxyContractAddress);
+ console.log("MASTER_MINTER_OWNER_ADDRESS: '%s'", masterMinterOwner);
+ }
+
+ /**
+ * @notice main function that will be run by forge
+ */
+ function run() external returns (MasterMinter) {
+ vm.startBroadcast(deployerPrivateKey);
+
+ // Now that the proxy contract has been deployed, we can deploy the master minter.
+ MasterMinter masterMinter = new MasterMinter(proxyContractAddress);
+
+ // Change the master minter to be owned by the master minter owner
+ masterMinter.transferOwnership(masterMinterOwner);
+
+ vm.stopBroadcast();
+
+ return masterMinter;
+ }
+}
diff --git a/scripts/git/diff-check.sh b/scripts/git/diff-check.sh
new file mode 100755
index 000000000..0272f53b1
--- /dev/null
+++ b/scripts/git/diff-check.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# =============
+# Utility script to check if two different commit hashes have the same content.
+# =============
+
+# The commit hashes to check.
+COMMIT_HASH=$1
+OTHER_COMMIT_HASH=$2
+
+if [ -z "$COMMIT_HASH" ] || [ -z "$OTHER_COMMIT_HASH" ]; then
+ echo "Usage: $0 "
+ exit 1;
+fi
+
+echo "Getting the tree-ish hash of the first commit"
+TREE_HASH=$(git cat-file commit $COMMIT_HASH | grep tree | sed 's/tree //g')
+echo ">> Commit: $COMMIT_HASH, Tree: $TREE_HASH"
+
+echo "Getting the tree-ish hash of the second commit"
+OTHER_TREE_HASH=$(git cat-file commit $OTHER_COMMIT_HASH | grep tree | sed 's/tree //g')
+echo ">> Commit: $OTHER_COMMIT_HASH, Tree: $OTHER_TREE_HASH"
+
+if [ $TREE_HASH = $OTHER_TREE_HASH ];
+then
+ echo "Both commits have the same content!";
+ exit 0;
+else
+ echo "Commits have different tree hashes. Content are different!";
+ exit 1;
+fi
diff --git a/scripts/git/rebase.sh b/scripts/git/rebase.sh
new file mode 100755
index 000000000..c24494146
--- /dev/null
+++ b/scripts/git/rebase.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# =============
+# Utility script to perform interactive rebases using an editor of choice.
+# =============
+
+# Husky should be disabled so that pre-commit hook run per 'reword' rebase.
+export HUSKY=0
+
+# (Optional) Choose the editor that you want to use for rebasing. For sufficiently
+# large rebases, it may be easier to use an editor with a GUI (eg. Sublime Text).
+export GIT_EDITOR="subl -n -w" # Sublime Text
+# GIT_EDITOR="vim"
+# GIT_EDITOR="nano"
+
+# The range of commits to rebase.
+FROM_COMMIT_HASH=$1
+TO_COMMIT_HASH=$2
+
+if [ -z "$FROM_COMMIT_HASH" ] || [ -z "$TO_COMMIT_HASH" ]; then
+ echo "Usage: $0 "
+ exit 1;
+fi
+
+echo "Interactive rebasing from '$FROM_COMMIT_HASH' to '$TO_COMMIT_HASH' using '$GIT_EDITOR'..."
+git rebase -i $FROM_COMMIT_HASH $TO_COMMIT_HASH
diff --git a/scripts/hardhat/alternativeArtifacts.ts b/scripts/hardhat/alternativeArtifacts.ts
new file mode 100644
index 000000000..34c0125ca
--- /dev/null
+++ b/scripts/hardhat/alternativeArtifacts.ts
@@ -0,0 +1,59 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ContractArtifact } from "./verifyOnChainBytecode";
+import * as fs from "fs";
+
+type AlternativeArtifact = Map;
+
+export enum ArtifactType {
+ OPMainnet = "OPMainnet",
+}
+
+const CACHED_ARTIFACTS_PATH = "./cached_artifacts/";
+
+// Read from https://optimistic.etherscan.io/token/0x0b2c639c533813f4aa9d7837caf62653d097ff85#code
+export const opMainnetFiatTokenProxyContractCreationBytecode = readCachedArtifact(
+ "opMainnetFiatTokenProxyContractCreationBytecode.bin"
+);
+const opMainnetFiatTokenProxyRuntimeBytecode = readCachedArtifact(
+ "opMainnetFiatTokenProxyRuntimeBytecode.bin"
+);
+
+const opMainnetArtifacts: AlternativeArtifact = new Map([
+ [
+ "FiatTokenProxy",
+ {
+ creationBytecode: opMainnetFiatTokenProxyContractCreationBytecode,
+ runtimeBytecode: opMainnetFiatTokenProxyRuntimeBytecode,
+ creationLinkReferences: {},
+ runtimeLinkReferences: {},
+ },
+ ],
+]);
+
+export const alternativeArtifacts: Map<
+ ArtifactType,
+ AlternativeArtifact
+> = new Map([[ArtifactType.OPMainnet, opMainnetArtifacts]]);
+
+function readCachedArtifact(filename: string): string {
+ return (
+ "0x" + fs.readFileSync(CACHED_ARTIFACTS_PATH + filename, "utf-8").trim()
+ );
+}
diff --git a/scripts/hardhat/downloadBlacklistedAccounts.ts b/scripts/hardhat/downloadBlacklistedAccounts.ts
new file mode 100644
index 000000000..426d24667
--- /dev/null
+++ b/scripts/hardhat/downloadBlacklistedAccounts.ts
@@ -0,0 +1,193 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Contract, ethers } from "ethers";
+import fs from "fs";
+import { task } from "hardhat/config";
+import { HardhatRuntimeEnvironment } from "hardhat/types";
+import _ from "lodash";
+import { hardhatArgumentTypes } from "./hardhatArgumentTypes";
+import { sleep } from "./helpers";
+import path from "path";
+
+const MAX_RETRIES = 5;
+const CHUNK_SIZE = 50000;
+const SLEEP_MS = 1000;
+const OUTPUT_FILE = path.join(__dirname, "..", "..", "blacklist.remote.json");
+
+type TaskArguments = {
+ proxyAddress: string;
+ startBlockNumber: number;
+};
+
+task(
+ "downloadBlacklistedAccounts",
+ "Downloads the blacklisted accounts on a FiatToken contract onto the local machine"
+)
+ .addParam(
+ "proxyAddress",
+ "The proxy address of the FiatToken contract",
+ undefined,
+ hardhatArgumentTypes.address
+ )
+ .addParam(
+ "startBlockNumber",
+ "The block number to start downloading from",
+ undefined,
+ hardhatArgumentTypes.int
+ )
+ .setAction(taskAction);
+
+async function taskAction(
+ { proxyAddress, startBlockNumber }: TaskArguments,
+ hre: HardhatRuntimeEnvironment
+) {
+ if (fs.existsSync(OUTPUT_FILE)) {
+ console.log(
+ `NOTE: '${OUTPUT_FILE}' exists. Will continue appending results to the file.`
+ );
+ }
+
+ const proxyAsBlacklistable = await hre.ethers.getContractAt(
+ "Blacklistable",
+ proxyAddress
+ );
+
+ const latestBlockNumber = await hre.ethers.provider.getBlockNumber();
+ let fromBlockNumber = startBlockNumber;
+ let toBlockNumber = Math.min(
+ latestBlockNumber,
+ startBlockNumber + CHUNK_SIZE
+ );
+
+ do {
+ await saveBlacklistedAccounts(
+ proxyAsBlacklistable,
+ fromBlockNumber,
+ toBlockNumber
+ );
+ fromBlockNumber = toBlockNumber + 1;
+ toBlockNumber = Math.min(latestBlockNumber, toBlockNumber + CHUNK_SIZE);
+
+ // Sleep for a bit to avoid blasting the RPC.
+ await sleep(SLEEP_MS);
+ } while (
+ toBlockNumber <= latestBlockNumber &&
+ fromBlockNumber < toBlockNumber
+ );
+}
+
+/**
+ * Saves all accounts that were blacklisted in [fromBlockNumber, toBlockNumber]
+ * AND are still blacklisted in storage.
+ */
+async function saveBlacklistedAccounts(
+ proxyAsBlacklistable: Contract,
+ fromBlockNumber: number,
+ toBlockNumber: number
+) {
+ console.log(
+ `Querying events in range [${fromBlockNumber}, ${toBlockNumber}]`
+ );
+ const rawBlacklistedEvents = await getBlacklistedEventsRetryWithBackoff(
+ proxyAsBlacklistable,
+ fromBlockNumber,
+ toBlockNumber
+ );
+ if (rawBlacklistedEvents.length <= 0) {
+ return;
+ }
+ console.log(`>> Found ${rawBlacklistedEvents.length} 'Blacklisted' events!`);
+
+ const maybeBlacklistedAccounts = _.uniq(
+ rawBlacklistedEvents.map((event) => {
+ const log = proxyAsBlacklistable.interface.parseLog(event);
+ return log?.args[0];
+ })
+ );
+ const blacklistedAccounts = [];
+ for (const account of maybeBlacklistedAccounts) {
+ if (await proxyAsBlacklistable.isBlacklisted(account)) {
+ blacklistedAccounts.push(account);
+ }
+ }
+
+ console.log(
+ `>> Found ${blacklistedAccounts.length} unique & currently blacklisted accounts`
+ );
+ if (blacklistedAccounts.length <= 0) {
+ return;
+ }
+
+ appendBlacklistedAccounts(blacklistedAccounts);
+}
+
+/**
+ * Appends blacklisted accounts to a JSON file, deduplicating accounts.
+ */
+function appendBlacklistedAccounts(blacklistedAccounts: string[]) {
+ let previousBlacklistedAccounts = [];
+ try {
+ previousBlacklistedAccounts = JSON.parse(
+ fs.readFileSync(OUTPUT_FILE, "utf-8")
+ );
+ } catch (e) {
+ console.error(
+ `Error found while parsing ${OUTPUT_FILE}. Overwriting its contents!`,
+ e
+ );
+ }
+
+ const indent = 2;
+ const accountsToWrite = _.chain(previousBlacklistedAccounts)
+ .concat(blacklistedAccounts)
+ .map(ethers.getAddress)
+ .uniq()
+ .value();
+
+ fs.writeFileSync(OUTPUT_FILE, JSON.stringify(accountsToWrite, null, indent));
+}
+
+/**
+ * Get all blacklisted events that were emitted in [fromBlockNumber, toBlockNumber]
+ * @throws error if RPC fails after MAX_RETRIES counts
+ */
+async function getBlacklistedEventsRetryWithBackoff(
+ proxyAsBlacklistable: Contract,
+ fromBlockNumber: number,
+ toBlockNumber: number
+) {
+ let tries = 0;
+ let error;
+
+ while (tries < MAX_RETRIES) {
+ await sleep(tries * SLEEP_MS);
+ try {
+ return await proxyAsBlacklistable.queryFilter(
+ proxyAsBlacklistable.filters.Blacklisted(),
+ fromBlockNumber,
+ toBlockNumber
+ );
+ } catch (e) {
+ error = e;
+ tries += 1;
+ }
+ }
+
+ throw error;
+}
diff --git a/scripts/hardhat/getContractCreationBlock.ts b/scripts/hardhat/getContractCreationBlock.ts
new file mode 100644
index 000000000..497d5f795
--- /dev/null
+++ b/scripts/hardhat/getContractCreationBlock.ts
@@ -0,0 +1,100 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { task } from "hardhat/config";
+import { hardhatArgumentTypes } from "./hardhatArgumentTypes";
+import { HardhatRuntimeEnvironment } from "hardhat/types";
+import { sleep } from "./helpers";
+
+type TaskArguments = {
+ contractAddress: string;
+};
+
+task(
+ "getContractCreationBlock",
+ "Gets the block number that a contract is created"
+)
+ .addPositionalParam(
+ "contractAddress",
+ "The contract address to query",
+ undefined,
+ hardhatArgumentTypes.address
+ )
+ .setAction(taskAction);
+
+async function taskAction(
+ { contractAddress }: TaskArguments,
+ hre: HardhatRuntimeEnvironment
+) {
+ const endBlock = await hre.ethers.provider.getBlockNumber();
+ const creationBlock = await getContractCreationBlock(
+ hre,
+ contractAddress,
+ 0,
+ endBlock
+ );
+ if (await isContractCreatedAtBlock(hre, contractAddress, creationBlock)) {
+ console.log(
+ `Contract '${contractAddress}' was created in block number ${creationBlock}`
+ );
+ } else {
+ console.log(
+ `Could not find contract creation block for contract '${contractAddress}'`
+ );
+ }
+}
+
+/**
+ * Searches for the creation block for a given contract using binary search.
+ * Adapted from https://levelup.gitconnected.com/how-to-get-smart-contract-creation-block-number-7f22f8952be0.
+ */
+async function getContractCreationBlock(
+ hre: HardhatRuntimeEnvironment,
+ contractAddress: string,
+ startBlock: number,
+ endBlock: number
+) {
+ await sleep(500);
+ console.log(`Searching in [${startBlock}, ${endBlock}]`);
+ if (startBlock === endBlock) {
+ return startBlock;
+ }
+ const midBlock = Math.floor((startBlock + endBlock) / 2);
+ if (await isContractCreatedAtBlock(hre, contractAddress, midBlock)) {
+ return getContractCreationBlock(hre, contractAddress, startBlock, midBlock);
+ } else {
+ return getContractCreationBlock(
+ hre,
+ contractAddress,
+ midBlock + 1,
+ endBlock
+ );
+ }
+}
+
+/**
+ * Checks if a given contract is created at a given block number
+ */
+async function isContractCreatedAtBlock(
+ hre: HardhatRuntimeEnvironment,
+ contractAddress: string,
+ block: number
+) {
+ const code = await hre.ethers.provider.getCode(contractAddress, block);
+ return code.length > 2;
+}
diff --git a/scripts/hardhat/hardhatArgumentTypes.ts b/scripts/hardhat/hardhatArgumentTypes.ts
new file mode 100644
index 000000000..b6cd190cf
--- /dev/null
+++ b/scripts/hardhat/hardhatArgumentTypes.ts
@@ -0,0 +1,60 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ethers } from "ethers";
+import { types } from "hardhat/config";
+import { HardhatError } from "hardhat/internal/core/errors";
+import { ERRORS } from "hardhat/internal/core/errors-list";
+import { CLIArgumentType } from "hardhat/types";
+
+/**
+ * Extended argument list from @see {@link https://github.com/NomicFoundation/hardhat/blob/f6eb9365fdc23033f41a8ff7744c9398c8e2459f/packages/hardhat-core/src/internal/core/params/argumentTypes.ts}
+ */
+const address: CLIArgumentType = {
+ name: "address",
+ parse: (_, strValue) => ethers.getAddress(strValue),
+ validate: (argName, value) => {
+ if (!ethers.isAddress(value)) {
+ throw new HardhatError(ERRORS.ARGUMENTS.INVALID_VALUE_FOR_TYPE, {
+ value,
+ name: argName,
+ type: address.name,
+ });
+ }
+ },
+};
+
+const oneOf = (values: unknown[]): CLIArgumentType => ({
+ name: "oneOf",
+ parse: (_, strValue) => strValue,
+ validate: (argName, value) => {
+ if (!values.includes(value)) {
+ throw new HardhatError(ERRORS.ARGUMENTS.INVALID_VALUE_FOR_TYPE, {
+ value,
+ name: argName,
+ type: oneOf.name,
+ });
+ }
+ },
+});
+
+export const hardhatArgumentTypes = {
+ ...types,
+ address,
+ oneOf,
+};
diff --git a/scripts/hardhat/helpers.ts b/scripts/hardhat/helpers.ts
new file mode 100644
index 000000000..cbe6c1722
--- /dev/null
+++ b/scripts/hardhat/helpers.ts
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { execSync } from "child_process";
+
+/**
+ * Utility function to trigger a sleep.
+ * @param ms the period to sleep for
+ */
+export async function sleep(ms: number): Promise {
+ await new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+/**
+ * Utility function to validate a supplied optimizerRuns
+ * @param optimizerRuns the supplied value for optimizerRuns
+ */
+export function validateOptimizerRuns(optimizerRuns: number): void {
+ if (!Number.isInteger(optimizerRuns) || optimizerRuns < 0) {
+ throw new Error("invalid optimizerRuns");
+ }
+}
+
+/**
+ * Wrapper for execSync so that execSync can be mocked in tests.
+ * Mocking execSync directly with Sinon results in the error
+ *"TypeError: Descriptor for property execSync is non-configurable and non-writable"
+ * @param command the command to execute
+ */
+export function execSyncWrapper(command: string): void {
+ execSync(command);
+}
diff --git a/scripts/hardhat/readValuesFromContract.ts b/scripts/hardhat/readValuesFromContract.ts
new file mode 100644
index 000000000..c48a71504
--- /dev/null
+++ b/scripts/hardhat/readValuesFromContract.ts
@@ -0,0 +1,116 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { task } from "hardhat/config";
+import { HardhatRuntimeEnvironment } from "hardhat/types";
+import _ from "lodash";
+import { hardhatArgumentTypes } from "./hardhatArgumentTypes";
+import { Contract } from "ethers";
+
+type TaskArguments = {
+ contractName: string;
+ contractAddress: string;
+ functionNames: string[];
+};
+
+task(
+ "readValuesFromContract",
+ "Calls a series of read-only functions with no arguments on a contract, and prints the results to console."
+)
+ .addParam(
+ "contractName",
+ "The contract name eg. FiatTokenV2_1",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .addParam(
+ "contractAddress",
+ "The address of the contract",
+ undefined,
+ hardhatArgumentTypes.address
+ )
+ .addVariadicPositionalParam(
+ "functionNames",
+ "The functions to call",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .setAction(taskAction);
+
+async function taskAction(
+ { contractName, contractAddress, functionNames }: TaskArguments,
+ hre: HardhatRuntimeEnvironment
+) {
+ const contract = await hre.ethers.getContractAt(
+ contractName,
+ contractAddress
+ );
+
+ if (contract.getDeployedCode() == null) {
+ throw new Error(`Cannot find contract at address '${contractAddress}'!`);
+ }
+
+ const viewFunctionResults = await Promise.all(
+ functionNames.map((funcName) =>
+ conditionallyReadValues(hre, contract, contractName, funcName)
+ )
+ );
+
+ const result = _.fromPairs(_.zip(functionNames, viewFunctionResults));
+ console.log(result);
+}
+
+/**
+ * Memory addresses for the return data of certain read-only functions
+ * on the FiatTokenProxy contract.
+ */
+const FiatTokenProxy_SLOT_ADDRESSES: Record = {
+ admin: "0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b",
+ implementation:
+ "0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3",
+};
+
+/**
+ * Conditionally calls a read-only function from a contract, depending on the contractName.
+ *
+ * If the contract is FiatTokenProxy, and either `name()` or `implementation()` is requested,
+ * then read the values from the storage addresses. Otherwise, get the result by calling the function.
+ */
+async function conditionallyReadValues(
+ hre: HardhatRuntimeEnvironment,
+ contract: Contract,
+ contractName: string,
+ functionName: string
+) {
+ if (!contract[functionName]) {
+ throw new Error(`Cannot find ${functionName} in contract!`);
+ }
+
+ if (
+ contractName === "FiatTokenProxy" &&
+ ["admin", "implementation"].includes(functionName)
+ ) {
+ const storageResult = await hre.ethers.provider.getStorage(
+ await contract.getAddress(),
+ FiatTokenProxy_SLOT_ADDRESSES[functionName]
+ );
+ return hre.ethers.getAddress("0x" + storageResult.slice(26));
+ }
+
+ return await contract[functionName].staticCall();
+}
diff --git a/scripts/hardhat/validateAccountsToBlacklist.ts b/scripts/hardhat/validateAccountsToBlacklist.ts
new file mode 100644
index 000000000..d5b753645
--- /dev/null
+++ b/scripts/hardhat/validateAccountsToBlacklist.ts
@@ -0,0 +1,178 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { task } from "hardhat/config";
+import { hardhatArgumentTypes } from "./hardhatArgumentTypes";
+
+import { HardhatRuntimeEnvironment } from "hardhat/types";
+import _ from "lodash";
+import path from "path";
+import { readBlacklistFile } from "../../utils";
+import { ethers } from "ethers";
+
+type TaskArguments = {
+ proxyAddress?: string;
+ v2_2UpgraderAddress?: string;
+ datasourceFilepath?: string;
+};
+
+task(
+ "validateAccountsToBlacklist",
+ "Validates blacklist.remote.json by checking that " +
+ "it matches with addresses retrieved from a separate datasource " +
+ "and/or it matches with V2_2Upgrader.accountsToBlacklist() " +
+ "and/or the list of addresses are currently blacklisted on FiatTokenProxy."
+)
+ .addOptionalParam(
+ "proxyAddress",
+ "The proxy address of the FiatToken contract. Runs comparison if set.",
+ undefined,
+ hardhatArgumentTypes.address
+ )
+ .addOptionalParam(
+ "upgraderAddress",
+ "The contract address of the deployed V2_2Upgrader. Runs comparison if set.",
+ undefined,
+ hardhatArgumentTypes.address
+ )
+ .addOptionalParam(
+ "datasourceFilepath",
+ "The JSON file containing an array of addresses retrieved from a separate datasource. Runs comparison if set.",
+ undefined,
+ hardhatArgumentTypes.inputFile
+ )
+ .setAction(taskAction);
+
+async function taskAction(
+ { proxyAddress, v2_2UpgraderAddress, datasourceFilepath }: TaskArguments,
+ hre: HardhatRuntimeEnvironment
+) {
+ console.log("Validation started");
+ const expectedAccountsToBlacklist = readBlacklistFile(
+ path.join(__dirname, "..", "..", "blacklist.remote.json")
+ );
+
+ // ==== Local state == Datasource's state
+ if (datasourceFilepath) {
+ console.log("Comparing local state with data source's state...");
+ console.log(
+ `>> Expecting ${expectedAccountsToBlacklist.length} accounts to blacklist`
+ );
+
+ const accountsFromDatasource = readBlacklistFile(datasourceFilepath);
+ console.log(
+ `>> Retrieved ${accountsFromDatasource.length} accounts from datasource`
+ );
+ console.log(">> Verifying accounts...");
+ verifyAccountsArrays(expectedAccountsToBlacklist, accountsFromDatasource);
+ console.log(">> All accounts verified!");
+ }
+
+ // ==== Local state == Upgrader state
+ if (v2_2UpgraderAddress) {
+ console.log("\nComparing local state with deployed V2_2Upgrader...");
+ const v2_2Upgrader = await hre.ethers.getContractAt(
+ "V2_2Upgrader",
+ v2_2UpgraderAddress
+ );
+ const accountsFromUpgrader = await v2_2Upgrader.accountsToBlacklist();
+ console.log(
+ `>> Retrieved ${accountsFromUpgrader.length} accounts from v2_2Upgrader`
+ );
+
+ console.log(">> Verifying accounts...");
+ verifyAccountsArrays(expectedAccountsToBlacklist, accountsFromUpgrader);
+ console.log(">> All accounts verified!");
+ }
+
+ // ==== Every account blacklisted
+ if (proxyAddress) {
+ console.log("\nComparing local state with deployed FiatTokenProxy...");
+ console.log(">> Validating that all accountsToBlacklist are blacklisted");
+ const proxyAsV2_1 = await hre.ethers.getContractAt(
+ "FiatTokenV2_1",
+ proxyAddress
+ );
+
+ for (let i = 0; i < expectedAccountsToBlacklist.length; i++) {
+ if (i % 5 === 0) {
+ console.log(
+ `>> Verified ${i}/${expectedAccountsToBlacklist.length} accounts`
+ );
+ }
+
+ const account = expectedAccountsToBlacklist[i];
+ if (!(await proxyAsV2_1.isBlacklisted(account))) {
+ throw new Error(`Account '${account}' is not currently blacklisted!`);
+ }
+ }
+ console.log(">> All accounts verified!");
+ }
+
+ console.log("Validation completed");
+}
+
+/**
+ * Verifies that two accounts array are both unique, and equal to each other.
+ */
+function verifyAccountsArrays(
+ accountsArray: string[],
+ otherAccountsArray: string[]
+) {
+ console.log(`>> Converting to checksum addresses`);
+ accountsArray = accountsArray.map(ethers.getAddress);
+ otherAccountsArray = otherAccountsArray.map(ethers.getAddress);
+
+ // Check for duplicates.
+ console.log(`>> Checking for duplicates in accountsArray`);
+ verifyUnique(accountsArray);
+
+ console.log(`>> Checking for duplicates in otherAccountsArray`);
+ verifyUnique(otherAccountsArray);
+
+ // Check array equality.
+ console.log(`>> Checking for array equality`);
+ if (accountsArray.length !== otherAccountsArray.length) {
+ throw new Error(
+ `Arrays have different lengths! Expected: ${accountsArray.length}, Actual: ${otherAccountsArray.length}`
+ );
+ }
+ for (const account of otherAccountsArray) {
+ if (!accountsArray.includes(account)) {
+ throw new Error(`Account '${account}' not found in accountsArray!`);
+ }
+ }
+}
+
+/**
+ * Verifies that an accounts array is unique.
+ */
+function verifyUnique(accountsArray: string[]) {
+ const duplicates = _.chain(accountsArray)
+ .groupBy((acc) => acc.toLowerCase())
+ .pickBy((group) => group.length > 1)
+ .keys()
+ .value();
+ if (duplicates.length !== 0) {
+ throw new Error(
+ `${duplicates.length} duplicates detected in array! ${JSON.stringify(
+ duplicates
+ )}`
+ );
+ }
+}
diff --git a/scripts/hardhat/verifyOnChainBytecode.ts b/scripts/hardhat/verifyOnChainBytecode.ts
new file mode 100644
index 000000000..16988d61f
--- /dev/null
+++ b/scripts/hardhat/verifyOnChainBytecode.ts
@@ -0,0 +1,541 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import bs58 from "bs58";
+import { decode } from "cbor";
+import { readFileSync } from "fs";
+import { task } from "hardhat/config";
+import { HardhatRuntimeEnvironment, LinkReferences } from "hardhat/types";
+import Hash from "ipfs-only-hash";
+import _ from "lodash";
+import path from "path";
+import { hardhatArgumentTypes } from "./hardhatArgumentTypes";
+import { alternativeArtifacts, ArtifactType } from "./alternativeArtifacts";
+import { execSyncWrapper, validateOptimizerRuns } from "./helpers";
+
+export type TaskArguments = {
+ contractName: string;
+ contractAddress: string;
+ libraryName?: string;
+ libraryAddress?: string;
+ verificationType: BytecodeVerificationType;
+ onchainBytecodeFilePath?: string;
+ isLibrary?: boolean;
+ metadataFilePath?: string;
+ contractCreationTxHash?: string;
+ useTracesForCreationBytecode?: boolean;
+ artifactType?: ArtifactType;
+ optimizerRuns?: number;
+};
+
+export enum BytecodeVerificationType {
+ Partial = "partial", // verifies the runtime bytecode without checking the metadata hash
+ Full = "full", // verifies the entire runtime bytecode including the metadata hash
+}
+
+export enum BytecodeInputType {
+ ConstructorCode = "constructor code", // Constructor bytecode (the portion that preceeds the runtime bytecode within the full creation bytecode)
+ RuntimeBytecodeFull = "full runtime bytecode", // Runtime bytecode including metadata hash
+ RuntimeBytecodePartial = "partial runtime bytecode", // Runtime bytecode excluding metadata hash
+ MetadataHash = "metadata hash",
+}
+
+export interface ContractArtifact {
+ creationBytecode: string;
+ runtimeBytecode: string;
+ creationLinkReferences: LinkReferences;
+ runtimeLinkReferences: LinkReferences;
+}
+
+interface GethTransactionTrace {
+ from: string;
+ to: string;
+ gas: string;
+ gasUsed: string;
+ input: string;
+ output?: string;
+ type: string;
+ value?: string;
+ calls?: GethTransactionTrace[];
+}
+
+type BytecodeComparisonResult = {
+ type: BytecodeInputType;
+ equal: boolean; // if the inputs are identical
+};
+
+task(
+ "verifyOnChainBytecode",
+ "Verify that the locally compiled bytecode matches the deployed bytecode on chain."
+)
+ .addParam(
+ "contractName",
+ "The name of the contract to validate",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .addParam(
+ "contractAddress",
+ "The address of the contract to validate",
+ undefined,
+ hardhatArgumentTypes.address
+ )
+ .addOptionalParam(
+ "libraryName",
+ "The name of the library contract the main contract uses",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .addOptionalParam(
+ "libraryAddress",
+ "The address of the library contract",
+ undefined,
+ hardhatArgumentTypes.address
+ )
+ .addOptionalParam(
+ "verificationType",
+ "Checks metadata if set to 'full', skips metadata checking if set to 'partial'.",
+ "partial",
+ hardhatArgumentTypes.oneOf(["full", "partial"])
+ )
+ .addOptionalParam(
+ "onchainBytecodeFilePath",
+ "Local file path that contains the deployed bytecode on chain. You can retrieve this using the eth_getCode RPC or from the 'Deployed Bytecode' section on Etherscan.",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .addOptionalParam(
+ "isLibrary",
+ "If the contract being verified is a library contract",
+ false,
+ hardhatArgumentTypes.boolean
+ )
+ .addOptionalParam(
+ "metadataFilePath",
+ "Local file path that contains the uploaded metadata",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .addOptionalParam(
+ "contractCreationTxHash",
+ "Transaction hash of the contract creation transaction",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .addOptionalParam(
+ "useTracesForCreationBytecode",
+ "Use transaction traces to pull the contract creation bytecode",
+ false,
+ hardhatArgumentTypes.boolean
+ )
+ .addOptionalParam(
+ "artifactType",
+ "The type of artifact to use for verification",
+ undefined,
+ hardhatArgumentTypes.string
+ )
+ .addOptionalParam(
+ "optimizerRuns",
+ "The optimizer runs to use to compile the contract",
+ undefined,
+ hardhatArgumentTypes.int
+ )
+ .setAction(taskAction);
+
+/**
+ * Wrapper function to pretty print the results of `verifyOnChainBytecode`.
+ */
+async function taskAction(
+ taskArguments: TaskArguments,
+ hre: HardhatRuntimeEnvironment
+): Promise {
+ const results = await verifyOnChainBytecode(taskArguments, hre);
+ logBytecodeComparisonResults(results);
+}
+
+/**
+ * A utility script to verify contract bytecode against locally compiled bytecode.
+ *
+ * Anatomy of contract bytecode:
+ * contract_creation_code =
+ * runtime_bytecode =
+ *
+ * Edge cases:
+ * 1) With solc v6 and v7, there's an anomoly where constants(strings) used by the constructor is added between `runtime_bytecode` and `constructor_arguments`
+ * 2) Runtime bytecode of contracts using external libraries has the address of the external library embedded
+ * 3) Runtime bytecode of library contracts has its own address embedded after the first PUSH instruction
+ */
+export async function verifyOnChainBytecode(
+ {
+ contractName,
+ contractAddress,
+ libraryName,
+ libraryAddress,
+ verificationType,
+ onchainBytecodeFilePath,
+ isLibrary,
+ metadataFilePath,
+ contractCreationTxHash,
+ useTracesForCreationBytecode,
+ artifactType,
+ optimizerRuns,
+ }: TaskArguments,
+ hre: HardhatRuntimeEnvironment
+): Promise {
+ if (optimizerRuns) {
+ validateOptimizerRuns(optimizerRuns);
+ execSyncWrapper(`forge build --optimizer-runs ${optimizerRuns}`);
+ }
+ const bytecodeComparisonResults = [];
+
+ // Getting contract bytecode from blockchain or local file input
+ let actualRuntimeBytecode;
+ if (onchainBytecodeFilePath) {
+ actualRuntimeBytecode = readFileSync(
+ path.join(__dirname, "..", "..", onchainBytecodeFilePath),
+ "utf-8"
+ );
+ } else {
+ actualRuntimeBytecode = await hre.ethers.provider.getCode(contractAddress);
+ }
+
+ const contractArtifact = getContractArtifact(contractName, artifactType);
+ const expectedCreationBytecode = contractArtifact.creationBytecode;
+ let expectedRuntimeBytecode = contractArtifact.runtimeBytecode;
+ const creationLinkReferences = contractArtifact.creationLinkReferences;
+ const runtimeLinkReferences = contractArtifact.runtimeLinkReferences;
+
+ // ==== Compare constructor code between contract on chain and locally compiled version
+ if (contractCreationTxHash) {
+ const actualCreationBytecode = await getContractCreationBytecode(
+ hre,
+ contractAddress,
+ contractCreationTxHash,
+ useTracesForCreationBytecode
+ );
+ const constructorCodeEndIndex = getConstructorCodeEndIndex(
+ expectedCreationBytecode,
+ expectedRuntimeBytecode,
+ libraryName,
+ creationLinkReferences,
+ runtimeLinkReferences
+ );
+
+ bytecodeComparisonResults.push({
+ type: BytecodeInputType.ConstructorCode,
+ equal:
+ // actual bytecode on chain
+ actualCreationBytecode.slice(0, constructorCodeEndIndex) ===
+ // expected bytecode from local compilation
+ expectedCreationBytecode.slice(0, constructorCodeEndIndex),
+ });
+ }
+
+ // ==== Replace embedded address in library contracts
+ // Library contract bytecode changes at deploy time. The contract address is embedded after the first push instruction
+ // https://docs.soliditylang.org/en/develop/contracts.html#call-protection-for-libraries
+ if (isLibrary) {
+ // Replace bytecode (4, 44) with contract address
+ const firstInstructionLength = 4;
+ expectedRuntimeBytecode =
+ expectedRuntimeBytecode.slice(0, firstInstructionLength) +
+ contractAddress.toLowerCase().slice(2) +
+ expectedRuntimeBytecode.slice(
+ firstInstructionLength + contractAddress.slice(2).length
+ );
+ }
+
+ // ==== For contracts that use external libraries, replace embedded library address with locally compiled bytecode with actual library addresses from user input.
+ if (libraryName && libraryAddress) {
+ const libraryReferencePositions: {
+ length: number;
+ start: number;
+ }[] = _.chain(runtimeLinkReferences)
+ .values()
+ .map(Object.entries)
+ .flatten()
+ .fromPairs()
+ .get(libraryName)
+ .value();
+
+ for (const position of libraryReferencePositions) {
+ const replacement = libraryAddress
+ .slice(2, 2 + position["length"] * 2)
+ .toLowerCase();
+ expectedRuntimeBytecode =
+ expectedRuntimeBytecode.slice(0, 2 + position.start * 2) +
+ replacement +
+ expectedRuntimeBytecode.slice(
+ 2 + position.start * 2 + position["length"] * 2
+ );
+ }
+ }
+
+ // ==== Compare runtime bytecode
+ if (verificationType === BytecodeVerificationType.Full) {
+ bytecodeComparisonResults.push({
+ type: BytecodeInputType.RuntimeBytecodeFull,
+ equal: expectedRuntimeBytecode === actualRuntimeBytecode,
+ });
+ } else {
+ bytecodeComparisonResults.push({
+ type: BytecodeInputType.RuntimeBytecodePartial,
+ equal:
+ removeMetadataHashAndMetadataLen(actualRuntimeBytecode) ===
+ removeMetadataHashAndMetadataLen(expectedRuntimeBytecode),
+ });
+ }
+
+ // ==== Compare user-supplied metadata file against metadata hash in deployed bytecode
+ if (metadataFilePath) {
+ const rawMetadata = readFileSync(
+ path.join(__dirname, "..", "..", metadataFilePath),
+ "utf-8"
+ );
+ const metadataHash = await Hash.of(rawMetadata); // the library output is bs58 encoded by default
+ const expectedMetadataHash = Buffer.from(
+ bs58.decode(metadataHash)
+ ).toString("hex");
+
+ const actualMetadataHash = getCborDecodedIpfsHash(actualRuntimeBytecode);
+
+ bytecodeComparisonResults.push({
+ type: BytecodeInputType.MetadataHash,
+ equal: expectedMetadataHash === actualMetadataHash,
+ });
+ }
+
+ return bytecodeComparisonResults;
+}
+
+export function logBytecodeComparisonResults(
+ results: BytecodeComparisonResult[]
+): void {
+ for (const { type, equal } of results) {
+ if (!equal) {
+ console.warn(
+ "\x1b[31m",
+ `\nWARNING: verification failed - ${type} mismatch.`
+ );
+ } else {
+ console.log(
+ "\x1b[32m",
+ `\nverification complete - supplied ${type} is consistent with local version.`
+ );
+ }
+ }
+}
+
+/**
+ * Returns contract creation bytecode
+ */
+async function getContractCreationBytecode(
+ hre: HardhatRuntimeEnvironment,
+ contractAddress: string,
+ contractCreationTxHash: string,
+ useTracesForCreationBytecode: boolean | undefined
+): Promise {
+ if (useTracesForCreationBytecode) {
+ const transactionTraces: GethTransactionTrace = await hre.ethers.provider.send(
+ "debug_traceTransaction",
+ [contractCreationTxHash, { tracer: "callTracer" }]
+ );
+ return extractBytecodeFromGethTraces(transactionTraces, contractAddress);
+ }
+ const transaction = await hre.ethers.provider.getTransaction(
+ contractCreationTxHash
+ );
+ if (transaction == null) {
+ throw new Error("Transaction not found");
+ }
+ return transaction.data;
+}
+
+/**
+ * Returns contract creation bytecode given traces
+ */
+export function extractBytecodeFromGethTraces(
+ traces: GethTransactionTrace,
+ targetContract: string
+): string {
+ if (
+ traces.to.toLowerCase() === targetContract.toLowerCase() &&
+ (traces.type === "CREATE" || traces.type === "CREATE2")
+ ) {
+ return traces.input;
+ }
+ if (traces.calls) {
+ for (const call of traces.calls) {
+ return extractBytecodeFromGethTraces(call, targetContract);
+ }
+ }
+ throw new Error("Contract creation trace not found");
+}
+
+/**
+ * Returns contract artifact
+ */
+function getContractArtifact(
+ contractName: string,
+ artifactType: ArtifactType | undefined
+): ContractArtifact {
+ if (artifactType !== undefined) {
+ return getAlternativeArtifact(contractName, artifactType);
+ }
+ // Getting locally compiled bytecode
+ const foundryContractArtifact = JSON.parse(
+ readFileSync(
+ path.join(
+ __dirname,
+ "..",
+ "..",
+ "artifacts",
+ "foundry",
+ `${contractName}.sol`,
+ `${contractName}.json`
+ ),
+ "utf-8"
+ )
+ );
+
+ return {
+ creationBytecode: foundryContractArtifact.bytecode.object,
+ runtimeBytecode: foundryContractArtifact.deployedBytecode.object,
+ creationLinkReferences: foundryContractArtifact.bytecode.linkReferences,
+ runtimeLinkReferences:
+ foundryContractArtifact.deployedBytecode.linkReferences,
+ };
+}
+
+/**
+ * Returns contract artifact from the static alternative artifacts
+ */
+function getAlternativeArtifact(
+ contractName: string,
+ artifactType: ArtifactType
+): ContractArtifact {
+ if (!Object.values(ArtifactType).includes(artifactType)) {
+ throw new Error(`artifact type ${artifactType} not supported`);
+ }
+ const alternativeArtifactContracts = alternativeArtifacts.get(
+ artifactType as ArtifactType
+ );
+ if (alternativeArtifactContracts === undefined) {
+ throw new Error(`artifacts not found for artifact type ${artifactType}`);
+ }
+ const contractArtifact = alternativeArtifactContracts.get(contractName);
+ if (contractArtifact === undefined) {
+ throw new Error(
+ `artifact not found for contract ${contractName} for artifact type ${artifactType}`
+ );
+ }
+
+ return contractArtifact;
+}
+
+/**
+ * Strips the metadata hash bytes from a contract's runtime bytecode. The hash is cbor-encoded and must
+ * be decoded to reveal the ipfs hash stored in the object.
+ *
+ * NOTE: This function only works for bytecode that are generated with "settings.metadata.bytecodeHash"
+ * set to default of "ipfs".
+ * @see {@link https://docs.soliditylang.org/en/latest/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode}
+ * for information about the metadata hash.
+ */
+function getCborDecodedIpfsHash(runtimeBytecode: string): string {
+ const metadataLength = getContractMetadataLength(runtimeBytecode);
+ const cborBytes = runtimeBytecode.slice(
+ runtimeBytecode.length - metadataLength,
+ runtimeBytecode.length - 4
+ );
+ const decodedCborBytes = decode(Buffer.from(cborBytes, "hex"));
+ if (!decodedCborBytes.ipfs) {
+ throw new Error(
+ "IPFS hash not detected. Metadata uploaded via alternative methods."
+ );
+ }
+ return decodedCborBytes.ipfs.toString("hex");
+}
+
+/**
+ * Returns contract runtime bytecode after the metadata hash has been stripped.
+ */
+function removeMetadataHashAndMetadataLen(runtimeBytecode: string): string {
+ const metadataLength = getContractMetadataLength(runtimeBytecode);
+ return runtimeBytecode.slice(0, runtimeBytecode.length - metadataLength);
+}
+
+/**
+ * Read last 4 digits of the contract runtime bytecode to determine the full length of the metadata hash
+ */
+function getContractMetadataLength(runtimeBytecode: string): number {
+ // Read the last two bytes to determine the length of the CBOR encoding
+ // https://docs.soliditylang.org/en/develop/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode
+ const metadataLengthHex = runtimeBytecode.slice(
+ runtimeBytecode.length - 4,
+ runtimeBytecode.length
+ );
+
+ const metadataNumBytes = parseInt(metadataLengthHex, 16);
+ return metadataNumBytes * 2 + metadataLengthHex.length;
+}
+
+/**
+ * Retrieves the index in the creation bytecode that partitions the constructor_code
+ * from the rest of the creation bytecode
+ *
+ * @returns {number} The last index in the creation bytecode that describes the constructor_code
+ */
+function getConstructorCodeEndIndex(
+ creationBytecode: string,
+ runtimeBytecode: string,
+ libraryName: string | undefined,
+ creationLinkReferences: LinkReferences,
+ runtimeLinkReferences: LinkReferences
+): number {
+ let constructorCodeEndIndex = -1;
+
+ if (!libraryName) {
+ // If the contract does not use external library contracts, the runtime bytecode should be a part of
+ // the contract creation code
+ constructorCodeEndIndex = creationBytecode.indexOf(
+ removeMetadataHashAndMetadataLen(runtimeBytecode).slice(2) // Remove "0x" at the beginning and metadata hash at end
+ );
+ } else {
+ // If the contract does reference a library contract, we can use the 1st library position as an anchor
+ // in the creation and runtime bytecode to align them. By shifting the cursor on the creation bytecode
+ // forward by length of the 1st library position, we should get the last index of the constructor code.
+ const getFirstLibStart = (linkReferences: LinkReferences): number => {
+ if (!linkReferences) {
+ throw new Error("Library link reference object is empty.");
+ }
+ const values = Object.values(linkReferences)[0];
+ const libRefs = values[libraryName];
+ if (!libRefs || !libRefs.length) {
+ throw new Error(`References to ${libraryName} library not found.`);
+ }
+ const startIndices: number[] = libRefs.map((a) => a.start);
+ return Math.min(...startIndices);
+ };
+ constructorCodeEndIndex =
+ (getFirstLibStart(creationLinkReferences) -
+ getFirstLibStart(runtimeLinkReferences)) *
+ 2;
+ }
+ return constructorCodeEndIndex;
+}
diff --git a/scripts/start-ganache.sh b/scripts/start-ganache.sh
deleted file mode 100755
index b01d31ccb..000000000
--- a/scripts/start-ganache.sh
+++ /dev/null
@@ -1 +0,0 @@
-./node_modules/ganache-cli/build/cli.node.js --defaultBalanceEther 1000000 --deterministic --a 15 > ganache-blockchain-log.txt &
\ No newline at end of file
diff --git a/scripts/verifyBridgedTokenBytecode.ts b/scripts/verifyBridgedTokenBytecode.ts
new file mode 100644
index 000000000..a42e57d2c
--- /dev/null
+++ b/scripts/verifyBridgedTokenBytecode.ts
@@ -0,0 +1,244 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import fs from "fs";
+import path from "path";
+import {
+ logBytecodeComparisonResults,
+ TaskArguments as VerifyOnChainBytecodeTaskArguments,
+ verifyOnChainBytecode,
+ BytecodeVerificationType,
+} from "./hardhat/verifyOnChainBytecode";
+import hre from "hardhat";
+import { HttpNetworkConfig } from "hardhat/types";
+import { ethers } from "ethers";
+import { ArtifactType } from "./hardhat/alternativeArtifacts";
+import { validateOptimizerRuns } from "./hardhat/helpers";
+
+type ContractInput = {
+ contractAddress: string;
+ contractCreationTxHash: string;
+ metadataFilePath: string;
+ verificationType?: BytecodeVerificationType;
+ artifactType?: ArtifactType;
+ useTracesForCreationBytecode?: boolean;
+ optimizerRuns?: number;
+};
+
+type InputObject = {
+ SignatureChecker: ContractInput;
+ FiatTokenV2_2: ContractInput;
+ FiatTokenProxy: ContractInput;
+ rpcUrl: string;
+};
+
+const VERIFICATION_ARTIFACTS_DIR = path.join(
+ __dirname,
+ "..",
+ "verification_artifacts"
+);
+
+async function main() {
+ const inputFilePath = path.join(VERIFICATION_ARTIFACTS_DIR, "input.json");
+
+ if (!fs.existsSync(inputFilePath)) {
+ throw new Error(
+ "No input files found. Please check your directory name and file name to make sure it is verification_artifacts/input.json"
+ );
+ }
+
+ if (hre.network.name !== "mainnet") {
+ throw new Error("Hardhat network must be set to 'mainnet'!");
+ }
+
+ let failedVerification = 0;
+ const input = validateInput(inputFilePath);
+ (hre.network.config as HttpNetworkConfig).url = input.rpcUrl;
+
+ const taskArgs = transformInputToVerifyOnChainBytecodeTaskArguments(input);
+ for (const taskArg of taskArgs) {
+ console.log(`\n Verifying on chain bytecode for: ${taskArg.contractName}`);
+ const results = await verifyOnChainBytecode(taskArg, hre);
+ logBytecodeComparisonResults(results);
+
+ for (const { equal } of results) {
+ if (!equal) {
+ failedVerification++;
+ }
+ }
+ }
+
+ if (failedVerification > 0) {
+ throw new Error("One or more verifications failed");
+ }
+}
+
+function validateInput(filename: string): InputObject {
+ const input = JSON.parse(fs.readFileSync(filename, "utf-8"));
+ if (
+ !input.SignatureChecker ||
+ !input.FiatTokenV2_2 ||
+ !input.FiatTokenProxy ||
+ !input.rpcUrl
+ ) {
+ throw new Error("Missing fields in input file!");
+ }
+ try {
+ // Formats a URL string. Throws a TypeError if the URL string is malformed.
+ input.rpcUrl = new URL(input.rpcUrl).toString();
+ } catch (e) {
+ throw new Error("Invalid URL!");
+ }
+ for (const key of ["SignatureChecker", "FiatTokenV2_2", "FiatTokenProxy"]) {
+ const value = input[key];
+ // Ensure all required fields exist
+ if (!value.contractAddress || !value.contractCreationTxHash) {
+ throw new Error(`Contract config for ${key} contains empty fields`);
+ }
+ // Validate contractAddress (must be a 20-byte address)
+ if (!ethers.isAddress(value.contractAddress)) {
+ throw new Error(
+ `Invalid contractAddress for ${key}: ${value.contractAddress}`
+ );
+ }
+ // Validate contractCreationTxHash (must be a 32-byte hash)
+ if (!ethers.isHexString(value.contractCreationTxHash, 32)) {
+ throw new Error(
+ `Invalid contractCreationTxHash for ${key}: ${value.contractCreationTxHash}`
+ );
+ }
+ // Validate verificationType if present
+ if (
+ value.verificationType !== undefined &&
+ !Object.values(BytecodeVerificationType).includes(value.verificationType)
+ ) {
+ throw new Error(
+ `Invalid verificationType for ${key}: ${value.verificationType}`
+ );
+ }
+ // Validate artifactType if present
+ if (
+ value.artifactType !== undefined &&
+ !Object.values(ArtifactType).includes(value.artifactType)
+ ) {
+ throw new Error(`Invalid artifactType for ${key}: ${value.artifactType}`);
+ }
+ // Validate useTracesForCreationBytecode if present
+ if (
+ value.useTracesForCreationBytecode !== undefined &&
+ typeof value.useTracesForCreationBytecode !== "boolean"
+ ) {
+ throw new Error(
+ `Invalid useTracesForCreationBytecode for ${key}: ${value.useTracesForCreationBytecode}`
+ );
+ }
+ // Validate optimizerRuns if present
+ if (value.optimizerRuns !== undefined) {
+ try {
+ validateOptimizerRuns(value.optimizerRuns);
+ } catch (e) {
+ throw new Error(
+ `Invalid optimizerRuns for ${key}: ${value.optimizerRuns}`
+ );
+ }
+ }
+
+ // If verification type isn't "full," validate metadataFilePath (file must exist)
+ if (value.verificationType !== BytecodeVerificationType.Full) {
+ const metadataFilePath = path.join(
+ VERIFICATION_ARTIFACTS_DIR,
+ `${key}.json`
+ );
+ if (!fs.existsSync(metadataFilePath)) {
+ throw new Error(
+ `Invalid metadataFilePath for ${key}: File does not exist`
+ );
+ }
+ }
+ }
+
+ return input as InputObject;
+}
+
+function transformInputToVerifyOnChainBytecodeTaskArguments(
+ input: InputObject
+): VerifyOnChainBytecodeTaskArguments[] {
+ // Impl Contract
+ const taskArgsImpl: VerifyOnChainBytecodeTaskArguments = {
+ contractName: "FiatTokenV2_2",
+ contractAddress: input.FiatTokenV2_2.contractAddress,
+ libraryName: "SignatureChecker",
+ libraryAddress: input.SignatureChecker.contractAddress,
+ isLibrary: false,
+ verificationType:
+ input.FiatTokenV2_2.verificationType || BytecodeVerificationType.Partial,
+ metadataFilePath:
+ input.FiatTokenV2_2.verificationType === BytecodeVerificationType.Full
+ ? undefined
+ : "verification_artifacts/FiatTokenV2_2.json",
+ contractCreationTxHash: input.FiatTokenV2_2.contractCreationTxHash,
+ useTracesForCreationBytecode:
+ input.FiatTokenV2_2.useTracesForCreationBytecode,
+ artifactType: input.FiatTokenV2_2.artifactType,
+ optimizerRuns: input.FiatTokenV2_2.optimizerRuns,
+ };
+
+ // Proxy
+ const taskArgsProxy: VerifyOnChainBytecodeTaskArguments = {
+ contractName: "FiatTokenProxy",
+ contractAddress: input.FiatTokenProxy.contractAddress,
+ isLibrary: false,
+ verificationType:
+ input.FiatTokenProxy.verificationType || BytecodeVerificationType.Partial,
+ metadataFilePath:
+ input.FiatTokenProxy.verificationType === BytecodeVerificationType.Full
+ ? undefined
+ : "verification_artifacts/FiatTokenProxy.json",
+ contractCreationTxHash: input.FiatTokenProxy.contractCreationTxHash,
+ useTracesForCreationBytecode:
+ input.FiatTokenProxy.useTracesForCreationBytecode,
+ artifactType: input.FiatTokenProxy.artifactType,
+ optimizerRuns: input.FiatTokenProxy.optimizerRuns,
+ };
+
+ // Signature Checker
+ const taskArgsLib: VerifyOnChainBytecodeTaskArguments = {
+ contractName: "SignatureChecker",
+ contractAddress: input.SignatureChecker.contractAddress,
+ isLibrary: true,
+ verificationType:
+ input.SignatureChecker.verificationType ||
+ BytecodeVerificationType.Partial,
+ metadataFilePath:
+ input.SignatureChecker.verificationType === BytecodeVerificationType.Full
+ ? undefined
+ : "verification_artifacts/SignatureChecker.json",
+ contractCreationTxHash: input.SignatureChecker.contractCreationTxHash,
+ useTracesForCreationBytecode:
+ input.SignatureChecker.useTracesForCreationBytecode,
+ artifactType: input.SignatureChecker.artifactType,
+ optimizerRuns: input.SignatureChecker.optimizerRuns,
+ };
+
+ return [taskArgsImpl, taskArgsProxy, taskArgsLib];
+}
+
+main().catch((error) => {
+ console.error(error);
+ process.exit(1);
+});
diff --git a/setup.sh b/setup.sh
new file mode 100755
index 000000000..0cd48f04e
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+# Refer to https://github.com/foundry-rs/foundry/tags for the list of Foundry versions.
+FOUNDRY_VERSION=nightly-f625d0fa7c51e65b4bf1e8f7931cd1c6e2e285e9
+
+if [[ "$CI" == "true" ]]
+then
+ echo "Skipping as we are in the CI";
+ exit;
+fi
+
+echo "Installing / Updating Foundry..."
+if ! command -v foundryup &> /dev/null
+then
+ echo "Installing foundryup..."
+ curl -L https://foundry.paradigm.xyz | bash
+
+ FOUNDRY_BASE_DIR=${XDG_CONFIG_HOME:-$HOME}
+ FOUNDRY_BIN_DIR="$FOUNDRY_BASE_DIR/.foundry/bin"
+ export PATH="$FOUNDRY_BIN_DIR:$PATH"
+fi
+
+if ! command -v forge &> /dev/null || [ ! "$(forge -V | grep -Eo '\b\w{7}\b')" = $(echo $FOUNDRY_VERSION | cut -c '9-15') ]
+then
+ echo "Installing foundry at $FOUNDRY_VERSION..."
+ foundryup --version $FOUNDRY_VERSION
+fi
+
+npm install -g dotenv-cli@7.3.0
+
+echo "Updating git submodules..."
+git submodule update --init --recursive
diff --git a/slither.config.json b/slither.config.json
deleted file mode 100644
index 22a1f3ffb..000000000
--- a/slither.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "detectors_to_exclude": "naming-convention,pragma,solc-version,timestamp"
-}
diff --git a/test.blacklist.remote.json b/test.blacklist.remote.json
new file mode 100644
index 000000000..0fed0f822
--- /dev/null
+++ b/test.blacklist.remote.json
@@ -0,0 +1,4 @@
+[
+ "0x04DBA1194ee10112fE6C3207C0687DEf0e78baCf",
+ "0xb6f5ec1A0a9cd1526536D3F0426c429529471F40"
+]
diff --git a/test/helpers/constants.ts b/test/helpers/constants.ts
index bad7c971f..1328aac48 100644
--- a/test/helpers/constants.ts
+++ b/test/helpers/constants.ts
@@ -1,9 +1,40 @@
-export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import BN from "bn.js";
+
+export const BLOCK_GAS_LIMIT = 30e6;
+// Hex values
+export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
export const ZERO_BYTES32 =
"0x0000000000000000000000000000000000000000000000000000000000000000";
-export const MAX_UINT256 =
+export const MAX_UINT256_HEX =
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
+export const POW_2_255_HEX =
+ "0x8000000000000000000000000000000000000000000000000000000000000000";
+export const POW_2_255_MINUS1_HEX =
+ "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
+
+// BigNumber values
+export const MAX_UINT256_BN = new BN(MAX_UINT256_HEX.slice(2), 16);
+export const POW_2_255_BN = new BN(POW_2_255_HEX.slice(2), 16);
+export const POW_2_255_MINUS1_BN = new BN(POW_2_255_MINUS1_HEX.slice(2), 16);
// derived from mnemonic: clarify final village pulse require old seek excite mushroom forest satoshi video
export const ACCOUNTS_AND_KEYS: { address: string; key: string }[] = [
@@ -68,3 +99,81 @@ export const ACCOUNTS_AND_KEYS: { address: string; key: string }[] = [
key: "db81ac68891890ec33021264ce81f9b5f9296a9fd95cdc785655db3066db2c08",
},
];
+
+export const HARDHAT_ACCOUNTS: string[] = [
+ "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
+ "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
+ "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
+ "0x90F79bf6EB2c4f870365E785982E1f101E93b906",
+ "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
+ "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
+ "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
+ "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",
+ "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f",
+ "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
+ "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
+ "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
+ "0xFABB0ac9d68B0B445fB7357272Ff202C5651694a",
+ "0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec",
+ "0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097",
+ "0xcd3B766CCDd6AE721141F452C550Ca635964ce71",
+ "0x2546BcD3c84621e976D8185a91A922aE77ECEc30",
+ "0xbDA5747bFD65F08deb54cb465eB87D40e51B197E",
+ "0xdD2FD4581271e230360230F9337D5c0430Bf44C0",
+ "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199",
+];
+
+export const HARDHAT_PRIVATE_KEYS: string[] = [
+ "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
+ "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d",
+ "5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a",
+ "7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6",
+ "47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a",
+ "8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba",
+ "92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e",
+ "4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356",
+ "dbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97",
+ "2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6",
+ "f214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897",
+ "701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82",
+ "a267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1",
+ "47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd",
+ "c526ee95bf44d8fc405a158bb884d9d1238d99f0612e9f33d006bb0789009aaa",
+ "8166f546bab6da521a8369cab06c5d2b9e46670292d85c875ee9ec20e84ffb61",
+ "ea6c44ac03bff858b476bba40716402b03e41b8e97e276d1baec7c37d42484a0",
+ "689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd",
+ "de9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0",
+ "df57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e",
+];
+
+export const accounts = {
+ deployerAccount: HARDHAT_ACCOUNTS[0],
+ arbitraryAccount: HARDHAT_ACCOUNTS[1],
+ tokenOwnerAccount: HARDHAT_ACCOUNTS[3],
+ blacklisterAccount: HARDHAT_ACCOUNTS[4],
+ arbitraryAccount2: HARDHAT_ACCOUNTS[5],
+ masterMinterAccount: HARDHAT_ACCOUNTS[6],
+ minterAccount: HARDHAT_ACCOUNTS[7],
+ pauserAccount: HARDHAT_ACCOUNTS[8],
+ mintOwnerAccount: HARDHAT_ACCOUNTS[9],
+ controller1Account: HARDHAT_ACCOUNTS[11],
+ rescuerAccount: HARDHAT_ACCOUNTS[12],
+ lostAndFoundAccount: HARDHAT_ACCOUNTS[13],
+ proxyOwnerAccount: HARDHAT_ACCOUNTS[14],
+};
+
+export const accountPrivateKeys = {
+ deployerAccount: HARDHAT_PRIVATE_KEYS[0],
+ arbitraryAccount: HARDHAT_PRIVATE_KEYS[1],
+ tokenOwnerAccount: HARDHAT_PRIVATE_KEYS[3],
+ blacklisterAccount: HARDHAT_PRIVATE_KEYS[4],
+ arbitraryAccount2: HARDHAT_PRIVATE_KEYS[5],
+ masterMinterAccount: HARDHAT_PRIVATE_KEYS[6],
+ minterAccount: HARDHAT_PRIVATE_KEYS[7],
+ pauserAccount: HARDHAT_PRIVATE_KEYS[8],
+ mintOwnerAccount: HARDHAT_PRIVATE_KEYS[9],
+ controller1Account: HARDHAT_PRIVATE_KEYS[11],
+ rescuerAccount: HARDHAT_PRIVATE_KEYS[12],
+ lostAndFoundAccount: HARDHAT_PRIVATE_KEYS[13],
+ proxyOwnerAccount: HARDHAT_PRIVATE_KEYS[14],
+};
diff --git a/test/helpers/index.ts b/test/helpers/index.ts
index e9ac56dca..f9c3e3b66 100644
--- a/test/helpers/index.ts
+++ b/test/helpers/index.ts
@@ -1,5 +1,40 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { ecsign } from "ethereumjs-util";
import { assert } from "chai";
+import { solidityPack } from "ethereumjs-abi";
+import {
+ FiatTokenProxyInstance,
+ FiatTokenV1_1Instance,
+ FiatTokenV1Instance,
+ FiatTokenV2_1Instance,
+ FiatTokenV2_2Instance,
+ FiatTokenV2Instance,
+ FiatTokenCeloV2_2Instance,
+} from "../../@types/generated";
+import _ from "lodash";
+
+const FiatTokenV1 = artifacts.require("FiatTokenV1");
+const FiatTokenV2 = artifacts.require("FiatTokenV2");
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+const FiatTokenV2_2 = artifacts.require("FiatTokenV2_2");
+const SignatureChecker = artifacts.require("SignatureChecker");
export async function expectRevert(
promise: Promise,
@@ -9,7 +44,7 @@ export async function expectRevert(
try {
await promise;
} catch (e) {
- err = e;
+ err = e as Error;
}
if (!err) {
@@ -18,10 +53,9 @@ export async function expectRevert(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const errMsg: string = (err as any).hijackedMessage ?? err.message;
- assert.match(errMsg, /revert/i);
if (!reason) {
- return;
+ assert.match(errMsg, /revert/i);
} else if (reason instanceof RegExp) {
assert.match(errMsg, reason);
} else {
@@ -51,6 +85,11 @@ export interface Signature {
s: string;
}
+export function packSignature(signature: Signature): Buffer {
+ const { v, r, s } = signature;
+ return solidityPack(["bytes32", "bytes32", "uint8"], [r, s, v]);
+}
+
export function ecSign(digest: string, privateKey: string): Signature {
const { v, r, s } = ecsign(
bufferFromHexString(digest),
@@ -63,3 +102,92 @@ export function ecSign(digest: string, privateKey: string): Signature {
export function bytes32FromAddress(address: string): string {
return prepend0x(strip0x(address).toLowerCase().padStart(64, "0"));
}
+
+export function makeDomainSeparator(
+ name: string,
+ version: string,
+ chainId: number,
+ address: string
+): string {
+ return web3.utils.keccak256(
+ web3.eth.abi.encodeParameters(
+ ["bytes32", "bytes32", "bytes32", "uint256", "address"],
+ [
+ web3.utils.keccak256(
+ "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
+ ),
+ web3.utils.keccak256(name),
+ web3.utils.keccak256(version),
+ chainId,
+ address,
+ ]
+ )
+ );
+}
+
+/**
+ * Helper function to generate a number of fake accounts.
+ * @param n the number of accounts to generate.
+ * @returns a list of accounts.
+ */
+export function generateAccounts(n: number): string[] {
+ return _.range(0, n).map(() => web3.eth.accounts.create().address);
+}
+
+export async function initializeToVersion(
+ proxyOrImplementation:
+ | FiatTokenProxyInstance
+ | FiatTokenV1Instance
+ | FiatTokenV1_1Instance
+ | FiatTokenV2Instance
+ | FiatTokenV2_1Instance
+ | FiatTokenV2_2Instance
+ | FiatTokenCeloV2_2Instance,
+ version: "1" | "1.1" | "2" | "2.1" | "2.2",
+ fiatTokenOwner: string,
+ lostAndFound: string,
+ accountsToBlacklist: string[] = []
+): Promise {
+ const proxyAsV1 = await FiatTokenV1.at(proxyOrImplementation.address);
+ await proxyAsV1.initialize(
+ "USDC",
+ "USDC",
+ "USD",
+ 6,
+ fiatTokenOwner,
+ fiatTokenOwner,
+ fiatTokenOwner,
+ fiatTokenOwner
+ );
+
+ if (version >= "2") {
+ const proxyAsV2 = await FiatTokenV2.at(proxyOrImplementation.address);
+ await proxyAsV2.initializeV2("USDC", {
+ from: fiatTokenOwner,
+ });
+ }
+
+ if (version >= "2.1") {
+ const proxyAsV2_1 = await FiatTokenV2_1.at(proxyOrImplementation.address);
+ await proxyAsV2_1.initializeV2_1(lostAndFound);
+ }
+
+ if (version >= "2.2") {
+ const proxyAsV2_2 = await FiatTokenV2_2.at(proxyOrImplementation.address);
+ await proxyAsV2_2.initializeV2_2(accountsToBlacklist, "USDCUSDC");
+ }
+}
+
+export async function linkLibraryToTokenContract<
+ T extends Truffle.ContractInstance
+>(tokenContract: Truffle.Contract): Promise {
+ try {
+ const signatureChecker = await SignatureChecker.new();
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ tokenContract.link(signatureChecker);
+ } catch (e) {
+ console.error(e);
+ // do nothing
+ }
+}
diff --git a/test/helpers/storageSlots.behavior.ts b/test/helpers/storageSlots.behavior.ts
index 6ff7b0381..f0f0921cf 100644
--- a/test/helpers/storageSlots.behavior.ts
+++ b/test/helpers/storageSlots.behavior.ts
@@ -1,29 +1,57 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import BN from "bn.js";
import { FiatTokenProxyInstance } from "../../@types/generated";
+import { HARDHAT_ACCOUNTS, POW_2_255_BN, ZERO_BYTES32 } from "./constants";
const FiatTokenProxy = artifacts.require("FiatTokenProxy");
const FiatTokenV1 = artifacts.require("FiatTokenV1");
const FiatTokenV1_1 = artifacts.require("FiatTokenV1_1");
+const FiatTokenV2 = artifacts.require("FiatTokenV2");
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+const FiatTokenV2_2 = artifacts.require("FiatTokenV2_2");
+
+export const STORAGE_SLOT_NUMBERS = {
+ _deprecatedBlacklisted: 3,
+ balanceAndBlacklistStates: 9,
+};
export function usesOriginalStorageSlotPositions<
T extends Truffle.ContractInstance
>({
Contract,
version,
- accounts,
}: {
Contract: Truffle.Contract;
- version: 1 | 1.1 | 2;
- accounts: Truffle.Accounts;
+ version: 1 | 1.1 | 2 | 2.1 | 2.2;
}): void {
describe("uses original storage slot positions", () => {
- const [name, symbol, currency, decimals] = ["USD Coin", "USDC", "USD", 6];
+ const [name, symbol, currency, decimals] = ["USDC", "USDC", "USD", 6];
const [mintAllowance, minted, transferred, allowance] = [
1000e6,
100e6,
30e6,
10e6,
];
+ const [mintedBN, transferredBN] = [minted, transferred].map(
+ (v) => new BN(v, 10)
+ );
const [
owner,
proxyAdmin,
@@ -35,10 +63,12 @@ export function usesOriginalStorageSlotPositions<
alice,
bob,
charlie,
- ] = accounts;
+ lostAndFound,
+ ] = HARDHAT_ACCOUNTS;
let fiatToken: T;
let proxy: FiatTokenProxyInstance;
+ let domainSeparator: string;
beforeEach(async () => {
fiatToken = await Contract.new();
@@ -63,6 +93,7 @@ export function usesOriginalStorageSlotPositions<
await proxyAsFiatTokenV1.mint(alice, minted, { from: minter });
await proxyAsFiatTokenV1.transfer(bob, transferred, { from: alice });
await proxyAsFiatTokenV1.approve(charlie, allowance, { from: alice });
+ await proxyAsFiatTokenV1.blacklist(bob, { from: blacklister });
await proxyAsFiatTokenV1.blacklist(charlie, { from: blacklister });
await proxyAsFiatTokenV1.pause({ from: pauser });
@@ -72,6 +103,19 @@ export function usesOriginalStorageSlotPositions<
from: owner,
});
}
+ if (version >= 2) {
+ const proxyAsFiatTokenV2 = await FiatTokenV2.at(proxy.address);
+ await proxyAsFiatTokenV2.initializeV2(name);
+ domainSeparator = await proxyAsFiatTokenV2.DOMAIN_SEPARATOR();
+ }
+ if (version >= 2.1) {
+ const proxyAsFiatTokenV2_1 = await FiatTokenV2_1.at(proxy.address);
+ await proxyAsFiatTokenV2_1.initializeV2_1(lostAndFound);
+ }
+ if (version >= 2.2) {
+ const proxyAsFiatTokenV2_2 = await FiatTokenV2_2.at(proxy.address);
+ await proxyAsFiatTokenV2_2.initializeV2_2([], symbol);
+ }
});
it("retains original storage slots 0 through 13", async () => {
@@ -81,140 +125,176 @@ export function usesOriginalStorageSlotPositions<
}
// slot 0 - owner
- expect(parseAddress(slots[0])).to.equal(owner); // owner
+ checkSlot(slots[0], [{ type: "address", value: owner }]); // owner
// slot 1 - pauser, paused
// values are lower-order aligned
- expect(parseInt(slots[1].slice(0, 2), 16)).to.equal(1); // paused
- expect(parseAddress(slots[1].slice(2))).to.equal(pauser); // pauser
+ checkSlot(slots[1], [
+ { type: "bool", value: true },
+ { type: "address", value: pauser },
+ ]); // paused + pauser
// slot 2 - blacklister
- expect(parseAddress(slots[2])).to.equal(blacklister); // blacklister
+ checkSlot(slots[2], [{ type: "address", value: blacklister }]); // blacklister
- // slot 3 - blacklisted (mapping, slot is unused)
- expect(slots[3]).to.equal("0");
+ // slot 3 - _deprecatedBlacklisted (mapping, slot is unused)
+ checkSlot(slots[3], ZERO_BYTES32);
// slot 4 - name
- expect(parseString(slots[4])).to.equal(name);
+ checkSlot(slots[4], [{ type: "string", value: name }]);
// slot 5 - symbol
- expect(parseString(slots[5])).to.equal(symbol);
+ checkSlot(slots[5], [{ type: "string", value: symbol }]);
// slot 6 - decimals
- expect(parseUint(slots[6]).toNumber()).to.equal(decimals);
+ checkSlot(slots[6], [{ type: "uint8", value: decimals }]);
// slot 7 - currency
- expect(parseString(slots[7])).to.equal(currency);
+ checkSlot(slots[7], [{ type: "string", value: currency }]);
// slot 8 - masterMinter, initialized
- expect(slots[8].slice(0, 2)).to.equal("01"); // initialized
- expect(parseAddress(slots[8].slice(2))).to.equal(masterMinter); // masterMinter
+ checkSlot(slots[8], [
+ { type: "bool", value: true },
+ { type: "address", value: masterMinter },
+ ]); // initialized + masterMinter
- // slot 9 - balances (mapping, slot is unused)
- expect(slots[9]).to.equal("0");
+ // slot 9 - balanceAndBlacklistStates (mapping, slot is unused)
+ checkSlot(slots[9], ZERO_BYTES32);
// slot 10 - allowed (mapping, slot is unused)
- expect(slots[10]).to.equal("0");
+ checkSlot(slots[10], ZERO_BYTES32);
// slot 11 - totalSupply
- expect(parseUint(slots[11]).toNumber()).to.equal(minted);
+ checkSlot(slots[11], [{ type: "uint256", value: minted }]);
// slot 12 - minters (mapping, slot is unused)
- expect(slots[12]).to.equal("0");
+ checkSlot(slots[12], ZERO_BYTES32);
// slot 13 - minterAllowed (mapping, slot is unused)
- expect(slots[13]).to.equal("0");
+ checkSlot(slots[13], ZERO_BYTES32);
});
if (version >= 1.1) {
it("retains slot 14 for rescuer", async () => {
const slot = await readSlot(proxy.address, 14);
- expect(parseAddress(slot)).to.equal(rescuer);
+ checkSlot(slot, [{ type: "address", value: rescuer }]);
+ });
+ }
+
+ if (version >= 2) {
+ it("retains slot 15 for DOMAIN_SEPARATOR", async () => {
+ const slot = await readSlot(proxy.address, 15);
+
+ // Cached domain separator is deprecated in v2.2. But we still need to ensure the storage slot is retained.
+ checkSlot(slot, domainSeparator);
});
}
- it("retains original storage slots for blacklisted mapping", async () => {
- // blacklisted[alice]
- let v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(alice, 3)),
- 16
+ it("retains original storage slots for _deprecatedBlacklisted mapping", async () => {
+ // _deprecatedBlacklisted[alice]
+ let slot = await readSlot(
+ proxy.address,
+ addressMappingSlot(alice, STORAGE_SLOT_NUMBERS._deprecatedBlacklisted)
);
- expect(v).to.equal(0);
+ checkSlot(slot, [{ type: "bool", value: false }]);
+
+ // _deprecatedBlacklisted[bob] - this should be set to true in pre-v2.2 versions,
+ // and left untouched in v2.2+ versions.
+ slot = await readSlot(
+ proxy.address,
+ addressMappingSlot(bob, STORAGE_SLOT_NUMBERS._deprecatedBlacklisted)
+ );
+ if (version >= 2.2) {
+ checkSlot(slot, [{ type: "bool", value: false }]);
+ } else {
+ checkSlot(slot, [{ type: "bool", value: true }]);
+ }
- // blacklisted[charlie]
- v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(charlie, 3)),
- 16
+ // _deprecatedBlacklisted[charlie] - this should be set to true in pre-v2.2 versions,
+ // and left untouched in v2.2+ versions.
+ slot = await readSlot(
+ proxy.address,
+ addressMappingSlot(charlie, STORAGE_SLOT_NUMBERS._deprecatedBlacklisted)
);
- expect(v).to.equal(1);
+ if (version >= 2.2) {
+ checkSlot(slot, [{ type: "bool", value: false }]);
+ } else {
+ checkSlot(slot, [{ type: "bool", value: true }]);
+ }
});
- it("retains original storage slots for balances mapping", async () => {
- // balance[alice]
- let v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(alice, 9)),
- 16
+ it("retains original storage slots for balanceAndBlacklistStates mapping", async () => {
+ // balanceAndBlacklistStates[alice] - not blacklisted, has balance
+ let slot = await readSlot(
+ proxy.address,
+ addressMappingSlot(
+ alice,
+ STORAGE_SLOT_NUMBERS.balanceAndBlacklistStates
+ )
);
- expect(v).to.equal(minted - transferred);
+ let expectedValue = mintedBN.sub(transferredBN);
+ checkSlot(slot, [{ type: "uint256", value: expectedValue }]);
- // balances[bob]
- v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(bob, 9)),
- 16
+ // balanceAndBlacklistStates[bob] - blacklisted, has balance
+ slot = await readSlot(
+ proxy.address,
+ addressMappingSlot(bob, STORAGE_SLOT_NUMBERS.balanceAndBlacklistStates)
+ );
+ expectedValue =
+ version >= 2.2 ? POW_2_255_BN.add(transferredBN) : transferredBN;
+ checkSlot(slot, [{ type: "uint256", value: expectedValue }]);
+
+ // balanceAndBlacklistStates[charlie] - blacklisted, no balance
+ slot = await readSlot(
+ proxy.address,
+ addressMappingSlot(
+ charlie,
+ STORAGE_SLOT_NUMBERS.balanceAndBlacklistStates
+ )
);
- expect(v).to.equal(transferred);
+ expectedValue = version >= 2.2 ? POW_2_255_BN : new BN(0);
+ checkSlot(slot, [{ type: "uint256", value: expectedValue }]);
});
it("retains original storage slots for allowed mapping", async () => {
// allowed[alice][bob]
- let v = parseInt(
- await readSlot(proxy.address, address2MappingSlot(alice, bob, 10)),
- 16
+ let slot = await readSlot(
+ proxy.address,
+ address2MappingSlot(alice, bob, 10)
);
- expect(v).to.equal(0);
+ checkSlot(slot, [{ type: "uint256", value: 0 }]);
+
// allowed[alice][charlie]
- v = parseInt(
- await readSlot(proxy.address, address2MappingSlot(alice, charlie, 10)),
- 16
+ slot = await readSlot(
+ proxy.address,
+ address2MappingSlot(alice, charlie, 10)
);
- expect(v).to.equal(allowance);
+ checkSlot(slot, [{ type: "uint256", value: allowance }]);
});
it("retains original storage slots for minters mapping", async () => {
// minters[minter]
- let v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(minter, 12)),
- 16
- );
- expect(v).to.equal(1);
+ let slot = await readSlot(proxy.address, addressMappingSlot(minter, 12));
+ checkSlot(slot, [{ type: "bool", value: true }]);
// minters[alice]
- v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(alice, 12)),
- 16
- );
- expect(v).to.equal(0);
+ slot = await readSlot(proxy.address, addressMappingSlot(alice, 12));
+ checkSlot(slot, [{ type: "bool", value: false }]);
});
it("retains original storage slots for minterAllowed mapping", async () => {
// minterAllowed[minter]
- let v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(minter, 13)),
- 16
- );
- expect(v).to.equal(mintAllowance - minted);
+ let slot = await readSlot(proxy.address, addressMappingSlot(minter, 13));
+ checkSlot(slot, [{ type: "uint256", value: mintAllowance - minted }]);
// minterAllowed[alice]
- v = parseInt(
- await readSlot(proxy.address, addressMappingSlot(alice, 13)),
- 16
- );
- expect(v).to.equal(0);
+ slot = await readSlot(proxy.address, addressMappingSlot(alice, 13));
+ checkSlot(slot, [{ type: "uint256", value: 0 }]);
});
});
}
-async function readSlot(
+export async function readSlot(
address: string,
slot: number | string
): Promise {
@@ -222,20 +302,55 @@ async function readSlot(
address,
slot as number // does support string, but type definition file is wrong
);
- return data.replace(/^0x/, "");
+ return data;
}
-function parseAddress(hex: string): string {
- return web3.utils.toChecksumAddress(hex.padStart(40, "0"));
-}
+function checkSlot(
+ slot: string,
+ expectations:
+ | { type: string; value: number | string | BN | boolean }[]
+ | string
+) {
+ if (typeof expectations === "string") {
+ expect(slot).to.equal(expectations);
+ } else {
+ const mappedExpectations = expectations.map((e) => {
+ if (e.type === "bool") {
+ return {
+ type: e.type,
+ value: e.value ? "true" : "",
+ };
+ }
+ return e;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ }) as any;
-function parseString(hex: string): string {
- const len = parseInt(hex.slice(-2), 16);
- return Buffer.from(hex.slice(0, len), "hex").toString("utf8");
-}
+ const encodePacked = web3.utils.encodePacked(...mappedExpectations);
+ if (!encodePacked) {
+ throw new Error("Error found while encoding!");
+ }
-function parseUint(hex: string): BN {
- return new BN(hex, 16);
+ let expectedSlotValue: string;
+
+ // Logic to validate slots containing a string or a byte.
+ // See: https://docs.soliditylang.org/en/v0.6.12/internals/layout_in_storage.html for
+ // the encoding logic.
+ if (
+ mappedExpectations.length === 1 &&
+ ["bytes", "string"].includes(mappedExpectations[0].type) &&
+ mappedExpectations[0].value.length < 32
+ ) {
+ const lastByte = (mappedExpectations[0].value.length * 2)
+ .toString(16)
+ .padStart(2, "0");
+ expectedSlotValue = `0x${encodePacked
+ .slice(2)
+ .padEnd(62, "0")}${lastByte}`;
+ } else {
+ expectedSlotValue = `0x${encodePacked.slice(2).padStart(64, "0")}`;
+ }
+ expect(slot).to.equal(expectedSlotValue);
+ }
}
function encodeUint(value: number | BN): string {
@@ -246,7 +361,7 @@ function encodeAddress(addr: string): string {
return addr.replace(/^0x/, "").toLowerCase().padStart(64, "0");
}
-function addressMappingSlot(addr: string, pos: number): string {
+export function addressMappingSlot(addr: string, pos: number): string {
return web3.utils.keccak256("0x" + encodeAddress(addr) + encodeUint(pos));
}
diff --git a/test/minting/AccountUtils.js b/test/minting/AccountUtils.js
new file mode 100644
index 000000000..b41b7e328
--- /dev/null
+++ b/test/minting/AccountUtils.js
@@ -0,0 +1,156 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// set to true to enable verbose logging in the tests
+const debugLogging = false;
+const assertDiff = require("assert-diff");
+assertDiff.options.strict = true;
+
+const Q = require("q");
+const { cloneDeep } = require("lodash");
+const util = require("util");
+
+const { accounts, accountPrivateKeys } = require("../helpers/constants");
+
+function addressEquals(address1, address2) {
+ if (address1.toUpperCase() === address2.toUpperCase()) {
+ return true;
+ } else {
+ assert.isFalse("expect " + address1 + " to equal " + address2);
+ }
+}
+
+// Returns an object with all named account values set to the default value
+// e.g sets {owner: 0, minter: 0,...}
+function setAccountDefault(accounts, defaultValue) {
+ const result = {};
+ for (const accountName in accounts) {
+ result[accountName] = defaultValue;
+ }
+ return result;
+}
+
+// return an expectedState that combines customState with the emptyState
+function buildExpectedPartialState(
+ emptyState,
+ customState,
+ ignoreExtraCustomVars
+) {
+ // for each item in customVars, set the item in expectedState
+ const expectedState = cloneDeep(emptyState);
+
+ for (const variableName in customState) {
+ // do I ignore extra values
+ if (Object.prototype.hasOwnProperty.call(expectedState, variableName)) {
+ const variableValue = customState[variableName];
+ if (isLiteral(variableValue)) {
+ expectedState[variableName] = variableValue;
+ } else {
+ // assume variableValue is a mapping evaluated on 1 or more accounts
+ for (const accountName in variableValue) {
+ expectedState[variableName][accountName] = variableValue[accountName];
+ }
+ }
+ } else if (!ignoreExtraCustomVars) {
+ throw new Error(
+ "variable " + variableName + " not found in expectedState"
+ );
+ }
+ }
+ return expectedState;
+}
+
+// For testing variance of specific variables from their default values.
+// customVars is an array of objects of the form,
+// {'variable': , 'expectedValue': }
+// to reference nested variables, name variable using dot syntax, e.g. 'allowance.arbitraryAccount.minterAccount'
+// emptyState: is the ideal empty state
+// getActualState: async function(token, accounts) => state
+// accounts: list of accounts on which to evaluate mappings
+// ignoreExtraCustomVars: ignore _customVars names that are not in the emptyState
+async function checkState(
+ _tokens,
+ _customVars,
+ emptyState,
+ getActualState,
+ accounts,
+ ignoreExtraCustomVars
+) {
+ // Iterate over array of tokens.
+ const numTokens = _tokens.length;
+ assert.equal(numTokens, _customVars.length);
+ let n;
+ for (n = 0; n < numTokens; n++) {
+ const token = _tokens[n];
+ const customVars = _customVars[n];
+ const expectedState = buildExpectedPartialState(
+ emptyState,
+ customVars,
+ ignoreExtraCustomVars
+ );
+
+ if (debugLogging) {
+ console.log(
+ util.inspect(expectedState, { showHidden: false, depth: null })
+ );
+ }
+
+ const actualState = await getActualState(token, accounts);
+ assertDiff.deepEqual(
+ actualState,
+ expectedState,
+ "difference between expected and actual state"
+ );
+ }
+}
+
+// accountQuery: an async function that takes as input an address and
+// queries the blockchain for a result
+// accounts: an object containing account addresses. Eg: {owner: 0xffad9033, minter: 0x45289432}
+// returns an object containing the results of calling accountQuery on each account
+// E.g. {owner: value1, minter: value2}
+async function getAccountState(accountQuery, _accounts) {
+ // create an array of promises
+ const promises = [];
+ for (const account in _accounts) {
+ const promiseQuery = accountQuery(accounts[account]);
+ promises.push(promiseQuery);
+ }
+ const results = await Q.allSettled(promises);
+ const state = {};
+ let u = 0;
+ for (const account in _accounts) {
+ state[account] = results[u].value;
+ ++u;
+ }
+ return state;
+}
+
+function isLiteral(object) {
+ if (typeof object === "object" && !object._isBigNumber) return false;
+ return true;
+}
+
+module.exports = {
+ Accounts: accounts,
+ AccountPrivateKeys: accountPrivateKeys,
+ setAccountDefault: setAccountDefault,
+ checkState: checkState,
+ getAccountState: getAccountState,
+ addressEquals: addressEquals,
+};
diff --git a/test/minting/ControllerTestUtils.js b/test/minting/ControllerTestUtils.js
new file mode 100644
index 000000000..f2ccf3cce
--- /dev/null
+++ b/test/minting/ControllerTestUtils.js
@@ -0,0 +1,70 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const Q = require("q");
+
+const { ZERO_ADDRESS } = require("../helpers/constants");
+const AccountUtils = require("./AccountUtils.js");
+const Accounts = AccountUtils.Accounts;
+const {
+ setAccountDefault,
+ checkState,
+ getAccountState,
+} = require("./AccountUtils.js");
+
+function ControllerState(owner, controllers) {
+ this.owner = owner;
+ this.controllers = controllers;
+ this.checkState = async function (controllerContract) {
+ await checkControllerState(controllerContract, this);
+ };
+}
+
+// Default state of Controller when it is deployed
+const controllerEmptyState = new ControllerState(
+ Accounts.mintOwnerAccount,
+ setAccountDefault(Accounts, ZERO_ADDRESS)
+);
+
+// Checks the state of an array of controller contracts
+async function checkControllerState(controller, customState) {
+ await checkState(
+ controller,
+ customState,
+ controllerEmptyState,
+ getActualControllerState,
+ Accounts,
+ true
+ );
+}
+
+// Gets the actual state of the controller contract.
+// Evaluates all mappings on the provided accounts.
+async function getActualControllerState(controllerContract, accounts) {
+ return Q.all([
+ controllerContract.owner.call(),
+ getAccountState(controllerContract.controllers, accounts),
+ ]).spread(function (owner, controllerState) {
+ return new ControllerState(owner, controllerState);
+ });
+}
+
+module.exports = {
+ controllerEmptyState: controllerEmptyState,
+ checkControllerState: checkControllerState,
+};
diff --git a/test/minting/MintControllerTests.js b/test/minting/MintControllerTests.js
new file mode 100644
index 000000000..9ff2e2283
--- /dev/null
+++ b/test/minting/MintControllerTests.js
@@ -0,0 +1,361 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const MintController = artifacts.require("minting/MintController");
+
+const {
+ newBigNumber,
+ checkMINTp0,
+ expectRevert,
+ expectError,
+ bigZero,
+} = require("../v1/helpers/tokenTest.js");
+
+const { cloneDeep } = require("lodash");
+
+const mintUtils = require("./MintControllerUtils.js");
+const AccountUtils = require("./AccountUtils.js");
+const Accounts = AccountUtils.Accounts;
+const initializeTokenWithProxyAndMintController =
+ mintUtils.initializeTokenWithProxyAndMintController;
+
+let rawToken;
+let tokenConfig;
+let token;
+let mintController;
+let expectedMintControllerState;
+let expectedTokenState;
+
+async function run_tests(newToken) {
+ beforeEach("Make fresh token contract", async function () {
+ rawToken = await newToken();
+ tokenConfig = await initializeTokenWithProxyAndMintController(
+ rawToken,
+ MintController
+ );
+ token = tokenConfig.token;
+ mintController = tokenConfig.mintController;
+ expectedMintControllerState = cloneDeep(tokenConfig.customState);
+ expectedTokenState = [
+ { variable: "masterMinter", expectedValue: mintController.address },
+ ];
+ });
+
+ it("should mint through mint controller", async function () {
+ const amount = 5000;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+
+ await token.mint(Accounts.arbitraryAccount, amount, {
+ from: Accounts.minterAccount,
+ });
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: newBigNumber(amount),
+ },
+ { variable: "totalSupply", expectedValue: newBigNumber(amount) }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("initial state", async function () {
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("only owner configures controller", async function () {
+ await expectRevert(
+ mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.minterAccount }
+ )
+ );
+ });
+
+ it("remove controller", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ await mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.controllers.controller1Account = bigZero;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("only owner can remove controller", async function () {
+ await expectRevert(
+ mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.minterAccount,
+ })
+ );
+ });
+
+ it("sets token", async function () {
+ await mintController.setMinterManager(mintController.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = mintController.address;
+ checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("only owner sets token", async function () {
+ await expectRevert(
+ mintController.setMinterManager(mintController.address, {
+ from: Accounts.minterAccount,
+ })
+ );
+ });
+
+ it("remove minter", async function () {
+ // create a minter
+ const amount = 500;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // remove minter
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedTokenState = [
+ { variable: "masterMinter", expectedValue: mintController.address },
+ ];
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("only controller removes a minter", async function () {
+ await expectError(
+ mintController.removeMinter({ from: Accounts.controller1Account }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("only controller configures a minter", async function () {
+ await expectError(
+ mintController.configureMinter(0, { from: Accounts.controller1Account }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("increment minter allowance", async function () {
+ // configure controller & minter
+ const amount = 500;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // increment minter allowance
+ await mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedTokenState = [
+ { variable: "masterMinter", expectedValue: mintController.address },
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount * 2),
+ },
+ ];
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("only controller increments allowance", async function () {
+ await expectError(
+ mintController.incrementMinterAllowance(0, {
+ from: Accounts.controller1Account,
+ }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("only active minters can have allowance incremented", async function () {
+ // configure controller but not minter
+ const amount = 500;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // increment minter allowance
+ await expectError(
+ mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ }),
+ "Can only increment allowance for minters in minterManager"
+ );
+ });
+
+ it("decrement minter allowance", async function () {
+ // configure controller & minter
+ const amount = 500;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // decrement minter allowance
+ await mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedTokenState = [
+ { variable: "masterMinter", expectedValue: mintController.address },
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ { variable: "minterAllowance.minterAccount", expectedValue: bigZero },
+ ];
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("only controller decrements allowance", async function () {
+ await expectError(
+ mintController.decrementMinterAllowance(0, {
+ from: Accounts.controller1Account,
+ }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("only active minters can have allowance decremented", async function () {
+ // configure controller but not minter
+ const amount = 500;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // decrement minter allowance
+ await expectError(
+ mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ }),
+ "Can only decrement allowance for minters in minterManager"
+ );
+ });
+}
+
+const wrapTests = require("../v1/helpers/wrapTests");
+wrapTests("MintController_Tests MintController", run_tests);
+
+module.exports = {
+ run_tests: run_tests,
+};
diff --git a/test/minting/MintControllerUtils.js b/test/minting/MintControllerUtils.js
new file mode 100644
index 000000000..3d35ce02e
--- /dev/null
+++ b/test/minting/MintControllerUtils.js
@@ -0,0 +1,89 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const {
+ bigZero,
+ initializeTokenWithProxy,
+} = require("../v1/helpers/tokenTest.js");
+
+const AccountUtils = require("./AccountUtils.js");
+const Accounts = AccountUtils.Accounts;
+const checkState = AccountUtils.checkState;
+
+const ControllerUtils = require("./ControllerTestUtils.js");
+const checkControllerState = ControllerUtils.checkControllerState;
+
+function MintControllerState(owner, controllers, minterManager) {
+ this.owner = owner;
+ this.controllers = controllers;
+ this.minterManager = minterManager;
+ this.checkState = async function (mintController) {
+ await checkMintControllerState(mintController, this);
+ };
+}
+
+// Default state of MintController when it is deployed
+const mintControllerEmptyState = new MintControllerState(null, {}, bigZero);
+// Checks the state of the mintController contract
+async function checkMintControllerState(mintController, customState) {
+ await checkControllerState(mintController, customState);
+ await checkState(
+ mintController,
+ customState,
+ mintControllerEmptyState,
+ getActualMintControllerState,
+ Accounts,
+ true
+ );
+}
+
+// Gets the actual state of the mintController contract.
+// Evaluates all mappings on the provided accounts.
+async function getActualMintControllerState(mintController) {
+ const minterManager = await mintController.minterManager.call();
+ return new MintControllerState(null, {}, minterManager);
+}
+
+// Deploys a FiatTokenV1 with a MintController contract as the masterMinter.
+// Uses the same workflow we would do in production - first deploy FiatToken then set the masterMinter.
+async function initializeTokenWithProxyAndMintController(
+ rawToken,
+ MintControllerArtifact
+) {
+ const tokenConfig = await initializeTokenWithProxy(rawToken);
+ const mintController = await MintControllerArtifact.new(
+ tokenConfig.token.address,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await tokenConfig.token.updateMasterMinter(mintController.address, {
+ from: Accounts.tokenOwnerAccount,
+ });
+ const tokenConfigWithMinter = {
+ proxy: tokenConfig.proxy,
+ token: tokenConfig.token,
+ mintController: mintController,
+ customState: new MintControllerState(null, {}, tokenConfig.token.address),
+ };
+ return tokenConfigWithMinter;
+}
+
+module.exports = {
+ initializeTokenWithProxyAndMintController: initializeTokenWithProxyAndMintController,
+ checkMintControllerState: checkMintControllerState,
+ MintControllerState: MintControllerState,
+};
diff --git a/test/minting/MintP0_ArgumentTests.js b/test/minting/MintP0_ArgumentTests.js
new file mode 100644
index 000000000..81c004cb6
--- /dev/null
+++ b/test/minting/MintP0_ArgumentTests.js
@@ -0,0 +1,494 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const MintController = artifacts.require("minting/MintController");
+const MasterMinter = artifacts.require("minting/MasterMinter");
+const FiatToken = artifacts.require("FiatTokenV1");
+
+const { MAX_UINT256_HEX, ZERO_ADDRESS } = require("../helpers/constants");
+const {
+ newBigNumber,
+ checkMINTp0,
+ expectRevert,
+ expectError,
+ bigZero,
+} = require("../v1/helpers/tokenTest.js");
+
+const { cloneDeep } = require("lodash");
+
+const mintUtils = require("./MintControllerUtils.js");
+const AccountUtils = require("./AccountUtils.js");
+const Accounts = AccountUtils.Accounts;
+const addressEquals = AccountUtils.addressEquals;
+const initializeTokenWithProxyAndMintController =
+ mintUtils.initializeTokenWithProxyAndMintController;
+
+async function run_tests_MintController(newToken, accounts) {
+ run_MINT_tests(newToken, MintController, accounts);
+}
+
+async function run_tests_MasterMinter(newToken, accounts) {
+ run_MINT_tests(newToken, MasterMinter, accounts);
+}
+
+let rawToken;
+let tokenConfig;
+let token;
+let mintController;
+let expectedMintControllerState;
+let expectedTokenState;
+
+async function run_MINT_tests(newToken, MintControllerArtifact) {
+ beforeEach("Make fresh token contract", async function () {
+ rawToken = await newToken();
+ tokenConfig = await initializeTokenWithProxyAndMintController(
+ rawToken,
+ MintControllerArtifact
+ );
+ token = tokenConfig.token;
+ mintController = tokenConfig.mintController;
+ expectedMintControllerState = cloneDeep(tokenConfig.customState);
+ expectedTokenState = [
+ { variable: "masterMinter", expectedValue: mintController.address },
+ ];
+ });
+
+ it("arg000 transferOwnership(msg.sender) works", async function () {
+ await mintController.transferOwnership(Accounts.mintOwnerAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg001 transferOwnership(0) reverts", async function () {
+ await expectRevert(
+ mintController.transferOwnership(ZERO_ADDRESS, {
+ from: Accounts.mintOwnerAccount,
+ })
+ );
+ });
+
+ it("arg002 transferOwnership(owner) works", async function () {
+ await mintController.transferOwnership(Accounts.mintOwnerAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg003 configureController(0, M) throws", async function () {
+ await expectError(
+ mintController.configureController(ZERO_ADDRESS, Accounts.minterAccount, {
+ from: Accounts.mintOwnerAccount,
+ }),
+ "Controller must be a non-zero address"
+ );
+ });
+
+ it("arg004 configureController(msg.sender, M) works", async function () {
+ await mintController.configureController(
+ Accounts.mintOwnerAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.mintOwnerAccount =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg005 configureController(M, M) works", async function () {
+ await mintController.configureController(
+ Accounts.minterAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.minterAccount =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg006 configureController(C, 0) throws", async function () {
+ await expectError(
+ mintController.configureController(
+ Accounts.controller1Account,
+ ZERO_ADDRESS,
+ { from: Accounts.mintOwnerAccount }
+ ),
+ "Worker must be a non-zero address"
+ );
+ });
+
+ it("arg007 removeController(0) throws", async function () {
+ // expect no changes
+ await expectError(
+ mintController.removeController(ZERO_ADDRESS, {
+ from: Accounts.mintOwnerAccount,
+ }),
+ "Controller must be a non-zero address"
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg008 setMinterManager(0) works", async function () {
+ await mintController.setMinterManager(ZERO_ADDRESS, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = ZERO_ADDRESS;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg009 setMinterManager(oldMinterManager) works", async function () {
+ await mintController.setMinterManager(token.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = token.address;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg010 setMinterManager(user_account) works", async function () {
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg011 setMinterManager(newToken) works", async function () {
+ const newToken = await FiatToken.new();
+ await mintController.setMinterManager(newToken.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = newToken.address;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg012 configureMinter(0) sets allowance to 0", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(0),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg013 configureMinter(oldAllowance) makes no changes", async function () {
+ const oldAllowance = 64738;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(oldAllowance, {
+ from: Accounts.controller1Account,
+ });
+ await mintController.configureMinter(oldAllowance, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(oldAllowance),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg014 configureMinter(MAX) works", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(MAX_UINT256_HEX, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(MAX_UINT256_HEX),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg015 incrementMinterAllowance(0) throws", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await expectError(
+ mintController.incrementMinterAllowance(0, {
+ from: Accounts.controller1Account,
+ }),
+ "Allowance increment must be greater than 0"
+ );
+ });
+
+ it("arg016 incrementMinterAllowance(oldAllowance) doubles the allowance", async function () {
+ const amount = 897;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ await mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(2 * amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg017 incrementMinterAllowance(MAX) throws", async function () {
+ const amount = 1;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ await expectRevert(
+ mintController.incrementMinterAllowance(MAX_UINT256_HEX, {
+ from: Accounts.controller1Account,
+ })
+ );
+ });
+
+ it("arg018 incrementMinterAllowance(BIG) throws", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(MAX_UINT256_HEX, {
+ from: Accounts.controller1Account,
+ });
+ await expectRevert(
+ mintController.incrementMinterAllowance(1, {
+ from: Accounts.controller1Account,
+ })
+ );
+ });
+
+ it("arg019 configureController(0, 0) throws", async function () {
+ await expectError(
+ mintController.configureController(ZERO_ADDRESS, ZERO_ADDRESS, {
+ from: Accounts.mintOwnerAccount,
+ }),
+ "Controller must be a non-zero address"
+ );
+ });
+
+ it("arg020 removeController(C) works", async function () {
+ // make controller1Account a controller
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ let actualMinter = await mintController.getWorker(
+ Accounts.controller1Account
+ );
+ addressEquals(Accounts.minterAccount, actualMinter);
+
+ // remove controller1Account
+ await mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ actualMinter = await mintController.getWorker(Accounts.controller1Account);
+ addressEquals(actualMinter, ZERO_ADDRESS);
+ });
+
+ it("arg021 removeController throws if worker is already address(0)", async function () {
+ // make controller1Account a controller
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ let actualMinter = await mintController.getWorker(
+ Accounts.controller1Account
+ );
+ addressEquals(Accounts.minterAccount, actualMinter);
+
+ // remove controller1Account
+ await mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ actualMinter = await mintController.getWorker(Accounts.controller1Account);
+ addressEquals(actualMinter, ZERO_ADDRESS);
+
+ // attempting to remove the controller1Account again should throw because the worker is already set to address(0).
+ await expectError(
+ mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.mintOwnerAccount,
+ }),
+ "Worker must be a non-zero address"
+ );
+ });
+
+ it("arg022 decrementMinterAllowance(oldAllowance) sets the allowance to 0", async function () {
+ const amount = 897;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ await mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ { variable: "minterAllowance.minterAccount", expectedValue: bigZero }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg023 decrementMinterAllowance(MIN) sets the allowance to 0", async function () {
+ const amount = 0;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ await mintController.decrementMinterAllowance(1, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ { variable: "minterAllowance.minterAccount", expectedValue: bigZero }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("arg024 decrementMinterAllowance(0) throws", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await expectError(
+ mintController.decrementMinterAllowance(0, {
+ from: Accounts.controller1Account,
+ }),
+ "Allowance decrement must be greater than 0"
+ );
+ });
+}
+
+const wrapTests = require("../v1/helpers/wrapTests");
+wrapTests("MINTp0_ArgumentTests MintController", run_tests_MintController);
+wrapTests("MINTp0_ArgumentTests MasterMinter", run_tests_MasterMinter);
diff --git a/test/minting/MintP0_BasicTests.js b/test/minting/MintP0_BasicTests.js
new file mode 100644
index 000000000..59dfe08e7
--- /dev/null
+++ b/test/minting/MintP0_BasicTests.js
@@ -0,0 +1,1439 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const { ZERO_ADDRESS, MAX_UINT256_HEX } = require("../helpers/constants");
+const MintController = artifacts.require("minting/MintController");
+const MasterMinter = artifacts.require("minting/MasterMinter");
+const FiatToken = artifacts.require("FiatTokenV1");
+
+const {
+ newBigNumber,
+ checkMINTp0,
+ expectRevert,
+ expectError,
+ bigZero,
+} = require("../v1/helpers/tokenTest.js");
+
+const { cloneDeep } = require("lodash");
+
+const mintUtils = require("./MintControllerUtils.js");
+const AccountUtils = require("./AccountUtils.js");
+const Accounts = AccountUtils.Accounts;
+const initializeTokenWithProxyAndMintController =
+ mintUtils.initializeTokenWithProxyAndMintController;
+
+const { getAccountState, addressEquals } = require("./AccountUtils.js");
+
+async function run_tests_MintController(newToken, accounts) {
+ run_MINT_tests(newToken, MintController, accounts);
+}
+
+async function run_tests_MasterMinter(newToken, accounts) {
+ run_MINT_tests(newToken, MasterMinter, accounts);
+}
+
+let rawToken;
+let tokenConfig;
+let token;
+let mintController;
+let expectedMintControllerState;
+let expectedTokenState;
+
+async function run_MINT_tests(newToken, MintControllerArtifact) {
+ beforeEach("Make fresh token contract", async function () {
+ rawToken = await newToken();
+ tokenConfig = await initializeTokenWithProxyAndMintController(
+ rawToken,
+ MintControllerArtifact
+ );
+ token = tokenConfig.token;
+ mintController = tokenConfig.mintController;
+ expectedMintControllerState = cloneDeep(tokenConfig.customState);
+ expectedTokenState = [
+ { variable: "masterMinter", expectedValue: mintController.address },
+ ];
+ });
+
+ it("bt001 Constructor - owner is msg.sender", async function () {
+ const newMintController = await MintController.new(token.address, {
+ from: Accounts.arbitraryAccount,
+ });
+ const owner = await newMintController.owner();
+ assert.isTrue(addressEquals(owner, Accounts.arbitraryAccount));
+ });
+
+ it("bt002 transferOwnership works when owner is msg.sender", async function () {
+ await mintController.transferOwnership(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.owner = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt003 transferOwnership reverts when owner is not msg.sender", async function () {
+ await expectRevert(
+ mintController.transferOwnership(Accounts.arbitraryAccount, {
+ from: Accounts.arbitraryAccount,
+ })
+ );
+ });
+
+ it("bt004 configureController works when owner is msg.sender", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt005 configureController reverts when owner is not msg.sender", async function () {
+ await expectRevert(
+ mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.arbitraryAccount }
+ )
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt006 setMinterManager works when owner is msg.sender", async function () {
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt007 setMinterManager reverts when owner is not msg.sender", async function () {
+ await expectRevert(
+ mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.arbitraryAccount,
+ })
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt008 removeController works when owner is msg.sender", async function () {
+ // add a controller
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // now remove it
+ await mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.controllers.controller1Account = ZERO_ADDRESS;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt009 removeController reverts when owner is not msg.sender", async function () {
+ // add a controller
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // fail to remove it
+ await expectRevert(
+ mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.arbitraryAccount,
+ })
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt010 removeMinter reverts when msg.sender is not a controller", async function () {
+ await expectError(
+ mintController.removeMinter({ from: Accounts.controller1Account }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("bt011 removeMinter sets minters[M] to 0", async function () {
+ // add a minter
+ const amount = 789;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // remove minter
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedTokenState.pop();
+ expectedTokenState.pop();
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt012 configureMinter reverts when msg.sender is not a controller", async function () {
+ await expectError(
+ mintController.configureMinter(50, { from: Accounts.controller1Account }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("bt013 configureMinter works when controllers[msg.sender]=M", async function () {
+ // add a controller
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+
+ // now configure minter
+ const amount = 6789;
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt014 incrementMinterAllowance reverts if msg.sender is not a controller", async function () {
+ await expectError(
+ mintController.incrementMinterAllowance(50, {
+ from: Accounts.controller1Account,
+ }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("bt015 incrementMinterAllowance works when controllers[msg.sender]=M", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ // now configure minter
+ const amount = 6789;
+ await mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt016 Constructor sets all controllers to 0", async function () {
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt017 removeController reverts when controllers[C] is 0", async function () {
+ // "remove" a controller that does not exist
+ await expectError(
+ mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.mintOwnerAccount,
+ }),
+ "Worker must be a non-zero address"
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt018 removeController removes an arbitrary controller", async function () {
+ // add a controller
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // now remove it
+ await mintController.removeController(Accounts.controller1Account, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.controllers.controller1Account = ZERO_ADDRESS;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt019 configureController works when controller[C]=0", async function () {
+ // note: this is a duplicate of bt004
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt020 configureController works when controller[C] != 0", async function () {
+ // set controllers[controller1Account]=minterAccount
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // now set controllers[controller1Account]=arbitraryAccount
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.arbitraryAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt021 configureController(C,C) works", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.controller1Account,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.controller1Account;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt022 configureController works when setting controller[C]=msg.sender", async function () {
+ await mintController.configureController(
+ Accounts.mintOwnerAccount,
+ Accounts.controller1Account,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.mintOwnerAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt023 configureController(C, newM) works when controller[C]=newM", async function () {
+ // set controllers[controller1Account]=minterAccount
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // now set controllers[controller1Account]=minterAccount
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt024 Constructor sets minterManager", async function () {
+ const minterManagerAddress = await mintController.getMinterManager();
+ assert.isTrue(addressEquals(token.address, minterManagerAddress));
+ });
+
+ it("bt026 setMinterManager(x) works when existing minterManager != 0", async function () {
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt027 setMinterManager(x) works when x = msg.sender", async function () {
+ await mintController.setMinterManager(Accounts.mintOwnerAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.mintOwnerAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt028 setMinterManager(x) works when x = minterManager", async function () {
+ const minterManagerAddress = await mintController.getMinterManager();
+ await mintController.setMinterManager(minterManagerAddress, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt030 removeMinter reverts when minterManager is 0", async function () {
+ // set minterManager
+ const minterManagerAddress = await mintController.getMinterManager();
+ await mintController.setMinterManager(minterManagerAddress, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = minterManagerAddress;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // configure minter will fail with any args
+ await expectRevert(
+ mintController.removeMinter({ from: Accounts.controller1Account })
+ );
+ });
+
+ it("bt031 removeMinter reverts when minterManager is a user account", async function () {
+ // set minterManager to user account
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // configure minter will fail with any args
+ await expectRevert(
+ mintController.removeMinter({ from: Accounts.controller1Account })
+ );
+ });
+
+ it("bt032 removeMinter works when minterManager is ok", async function () {
+ // add a minter
+ const amount = 3;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // remove minter
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedTokenState.pop();
+ expectedTokenState.pop();
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt034 configureMinter reverts when minterManager is a user account", async function () {
+ // set minterManager to user account
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // configure minter will fail with any args
+ await expectRevert(
+ mintController.configureMinter(50, { from: Accounts.controller1Account })
+ );
+ });
+
+ it("bt035 configureMinter works when minterManager is ok", async function () {
+ const amount = 456;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt037 incrementMinterAllowance reverts when minterManager is a user account", async function () {
+ // set minterManager to user account
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // incrementMinterAllowance will fail with any args
+ await expectRevert(
+ mintController.incrementMinterAllowance(50, {
+ from: Accounts.controller1Account,
+ })
+ );
+ });
+
+ it("bt038 incrementMinterAllowance works when minterManager is ok", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ // now incrementMinterAllowance
+ const amount = 45;
+ await mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt039 configureMinter(M, amt) works when minterManager.isMinter(M)=false", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+ assert.isFalse(isMinter);
+
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt040 configureMinter(M, amt) works when minterManager.isMinter(M)=true", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+ assert.isTrue(isMinter);
+
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt041 removeMinter(M) works when minterManager.isMinter(M)=false", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+ assert.isFalse(isMinter);
+
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt042 removeMinter(M) works when minterManager.isMinter(M)=true", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+ assert.isTrue(isMinter);
+
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt043 incrementMinterAllowance(M, amt) reverts when minterManager.isMinter(M)=false", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+ assert.isFalse(isMinter);
+
+ await expectError(
+ mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ }),
+ "Can only increment allowance for minters in minterManager"
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt044 incrementMinterAllowance(M, amt) works when minterManager.isMinter(M)=true", async function () {
+ const amount = 65424;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+ assert.isTrue(isMinter);
+
+ await mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt045 constructor - minterManager.isMinter[ALL] is false", async function () {
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+
+ const isMinterMappingEval = async function (accountAddress) {
+ return await minterManager.isMinter(accountAddress);
+ };
+
+ const isMinterResults = await getAccountState(
+ isMinterMappingEval,
+ Accounts
+ );
+ for (const account in Accounts) {
+ assert.isFalse(isMinterResults[account]);
+ }
+ });
+
+ it("bt046 constructor - minterManager.minterAllowance[ALL] = 0", async function () {
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+
+ const minterAllowanceMapping = async function (accountAddress) {
+ return await minterManager.minterAllowance(accountAddress);
+ };
+
+ const minterAllowanceResults = await getAccountState(
+ minterAllowanceMapping,
+ Accounts
+ );
+ for (const account in Accounts) {
+ assert(minterAllowanceResults[account].isZero());
+ }
+ });
+
+ it("bt047 incrementMinterAllowance(M,amt) works when minterAllowance is 0", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.isZero());
+
+ await mintController.incrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt048 incrementMinterAllowance(M, amt) works when minterAllowance > 0", async function () {
+ const initialAmount = 987341;
+ const incrementAmount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(initialAmount, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.cmp(newBigNumber(initialAmount)) === 0);
+
+ await mintController.incrementMinterAllowance(incrementAmount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(initialAmount + incrementAmount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt049 incrementMinterAllowance(M,amt) reverts when minterAllowance[M] + amt > 2^256", async function () {
+ const initialAmount =
+ "0x" +
+ newBigNumber(MAX_UINT256_HEX).sub(newBigNumber(45)).toString(16, 64);
+ const incrementAmount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(initialAmount, {
+ from: Accounts.controller1Account,
+ });
+
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(initialAmount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ await expectRevert(
+ mintController.incrementMinterAllowance(incrementAmount, {
+ from: Accounts.controller1Account,
+ })
+ );
+ });
+
+ it("bt050 configureMinter(M,amt) works when minterAllowance=0", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.cmp(newBigNumber(0)) === 0);
+
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt051 configureMinter(M,amt) works when minterAllowance>0", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.cmp(newBigNumber(amount)) === 0);
+
+ await mintController.configureMinter(2 * amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(2 * amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt052 configureMinter(M,amt) works when amt+minterAllowance > 2^256", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(MAX_UINT256_HEX, {
+ from: Accounts.controller1Account,
+ });
+
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(amount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt053 removeMinter works when the minterAllowance is 0", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.isZero());
+
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt054 removeMinter works when the minterAllowance is not zero", async function () {
+ const amount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.cmp(newBigNumber(amount)) === 0);
+
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt055 removeMinter works when the minterAllowance is big", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(MAX_UINT256_HEX, {
+ from: Accounts.controller1Account,
+ });
+
+ await mintController.removeMinter({ from: Accounts.controller1Account });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt056 decrementMinterAllowance reverts if msg.sender is not a controller", async function () {
+ await expectError(
+ mintController.decrementMinterAllowance(0, {
+ from: Accounts.controller1Account,
+ }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ });
+
+ it("bt057 decrementMinterAllowance works when controllers[msg.sender]=M", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(6789, {
+ from: Accounts.controller1Account,
+ });
+
+ // now configure minter
+ const amount = 1;
+ await mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(6788),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt058 decrementMinterAllowance reverts when minterManager is 0", async function () {
+ // set minterManager to zero
+ await mintController.setMinterManager(ZERO_ADDRESS, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = ZERO_ADDRESS;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // decrementMinterAllowance will fail with any args
+ await expectRevert(
+ mintController.decrementMinterAllowance(1, {
+ from: Accounts.controller1Account,
+ })
+ );
+ });
+
+ it("bt059 decrementMinterAllowance reverts when minterManager is a user account", async function () {
+ // set minterManager to user account
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // decrementMinterAllowance will fail with any args
+ await expectRevert(
+ mintController.decrementMinterAllowance(1, {
+ from: Accounts.controller1Account,
+ })
+ );
+ });
+
+ it("bt060 decrementMinterAllowance works when minterManager is ok", async function () {
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(45, {
+ from: Accounts.controller1Account,
+ });
+
+ // now decrementMinterAllowance
+ const amount = 45;
+ await mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ { variable: "minterAllowance.minterAccount", expectedValue: bigZero }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt061 decrementMinterAllowance(M, amt) reverts when minterManager.isMinter(M)=false", async function () {
+ const amount = 1;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+
+ assert.isFalse(isMinter);
+
+ await expectError(
+ mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ }),
+ "Can only decrement allowance for minters in minterManager"
+ );
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt062 decrementMinterAllowance(M, amt) works when minterManager.isMinter(M)=true", async function () {
+ const amount = 65424;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const isMinter = await minterManager.isMinter(Accounts.minterAccount);
+ assert.isTrue(isMinter);
+
+ await mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ { variable: "minterAllowance.minterAccount", expectedValue: bigZero }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt063 decrementMinterAllowance(M,amt) works when minterAllowance is MAX", async function () {
+ const amount = MAX_UINT256_HEX;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(amount, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.cmp(newBigNumber(MAX_UINT256_HEX)) === 0);
+ await mintController.decrementMinterAllowance(amount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ { variable: "minterAllowance.minterAccount", expectedValue: bigZero }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt064 decrementMinterAllowance(M, amt) works when minterAllowance > 0", async function () {
+ const initialAmount = 987341;
+ const decrementAmount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(initialAmount, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.cmp(newBigNumber(initialAmount)) === 0);
+
+ await mintController.decrementMinterAllowance(decrementAmount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(initialAmount - decrementAmount),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("bt065 decrementMinterAllowance(M,amt) sets allowance to 0 when minterAllowance[M] - amt < 0", async function () {
+ const initialAmount = 45;
+ const decrementAmount = 64;
+ await mintController.configureController(
+ Accounts.controller1Account,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(initialAmount, {
+ from: Accounts.controller1Account,
+ });
+
+ const minterManager = await FiatToken.at(
+ await mintController.getMinterManager()
+ );
+ const minterAllowance = await minterManager.minterAllowance(
+ Accounts.minterAccount
+ );
+ assert(minterAllowance.cmp(newBigNumber(initialAmount)) === 0);
+ await mintController.decrementMinterAllowance(decrementAmount, {
+ from: Accounts.controller1Account,
+ });
+ expectedMintControllerState.controllers.controller1Account =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ { variable: "minterAllowance.minterAccount", expectedValue: bigZero }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+}
+
+const wrapTests = require("../v1/helpers/wrapTests");
+wrapTests("MINTp0_BasicTests MintController", run_tests_MintController);
+wrapTests("MINTp0_BasicTests MasterMinter", run_tests_MasterMinter);
diff --git a/test/minting/MintP0_EndToEndTests.js b/test/minting/MintP0_EndToEndTests.js
new file mode 100644
index 000000000..43072f4cb
--- /dev/null
+++ b/test/minting/MintP0_EndToEndTests.js
@@ -0,0 +1,683 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const MintController = artifacts.require("minting/MintController");
+const MasterMinter = artifacts.require("minting/MasterMinter");
+
+const {
+ newBigNumber,
+ checkMINTp0,
+ expectRevert,
+ expectError,
+ initializeTokenWithProxy,
+} = require("../v1/helpers/tokenTest.js");
+
+const { cloneDeep } = require("lodash");
+
+const mintUtils = require("./MintControllerUtils.js");
+const AccountUtils = require("./AccountUtils.js");
+const Accounts = AccountUtils.Accounts;
+const initializeTokenWithProxyAndMintController =
+ mintUtils.initializeTokenWithProxyAndMintController;
+
+let mintController;
+let expectedMintControllerState;
+let expectedTokenState;
+let token;
+let rawToken;
+let tokenConfig;
+
+async function run_tests_MintController(newToken, accounts) {
+ run_MINT_tests(newToken, MintController, accounts);
+}
+
+async function run_tests_MasterMinter(newToken, accounts) {
+ run_MINT_tests(newToken, MasterMinter, accounts);
+}
+
+async function run_MINT_tests(newToken, MintControllerArtifact) {
+ beforeEach("Make fresh token contract", async function () {
+ rawToken = await newToken();
+ tokenConfig = await initializeTokenWithProxyAndMintController(
+ rawToken,
+ MintControllerArtifact
+ );
+ token = tokenConfig.token;
+ mintController = tokenConfig.mintController;
+ expectedMintControllerState = cloneDeep(tokenConfig.customState);
+ expectedTokenState = [
+ { variable: "masterMinter", expectedValue: mintController.address },
+ ];
+ });
+
+ it("ete000 New owner can configure controllers", async function () {
+ await mintController.transferOwnership(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await mintController.configureController(
+ Accounts.arbitraryAccount2,
+ Accounts.minterAccount,
+ { from: Accounts.arbitraryAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount2 =
+ Accounts.minterAccount;
+ expectedMintControllerState.owner = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete001 New owner can remove controllers", async function () {
+ await mintController.transferOwnership(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await mintController.configureController(
+ Accounts.arbitraryAccount2,
+ Accounts.minterAccount,
+ { from: Accounts.arbitraryAccount }
+ );
+ await mintController.removeController(Accounts.arbitraryAccount2, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedMintControllerState.owner = Accounts.arbitraryAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete002 New controller can configure minter", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(10),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete003 Configure two controllers for the same minter and make sure they can both configureMinter", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureController(
+ Accounts.arbitraryAccount2,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedMintControllerState.controllers.arbitraryAccount2 =
+ Accounts.minterAccount;
+
+ // first controller configures minter
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(10),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // second controller configures minter
+ await mintController.configureMinter(30, {
+ from: Accounts.arbitraryAccount2,
+ });
+ expectedTokenState.push({
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(30),
+ });
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete004 Configure two controllers for the same minter, one adds a minter and the other removes it", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureController(
+ Accounts.arbitraryAccount2,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedMintControllerState.controllers.arbitraryAccount2 =
+ Accounts.minterAccount;
+
+ // first controller configures minter
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(10),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // second controller remove minter
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount2 });
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: false },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(0),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete005 Configure two controllers for different minters and make sure 2nd cant remove", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureController(
+ Accounts.arbitraryAccount2,
+ Accounts.pauserAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedMintControllerState.controllers.arbitraryAccount2 =
+ Accounts.minterAccount;
+
+ // first controller configures minter
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(10),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // second controller fails to remove minter (expectedTokenState unchanged)
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount2 });
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete006 Configure two controllers for different minters and make sure 2nd cant configure", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureController(
+ Accounts.arbitraryAccount2,
+ Accounts.pauserAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedMintControllerState.controllers.arbitraryAccount2 =
+ Accounts.minterAccount;
+
+ // second controller fails to configure minter (configures pauser instead)
+ await mintController.configureMinter(20, {
+ from: Accounts.arbitraryAccount2,
+ });
+ expectedTokenState.push(
+ { variable: "isAccountMinter.pauserAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.pauserAccount",
+ expectedValue: newBigNumber(20),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete007 Remove a controller and make sure it can't modify minter", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.removeController(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ await expectError(
+ mintController.configureMinter(10, { from: Accounts.arbitraryAccount }),
+ "The value of controllers[msg.sender] must be non-zero"
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete008 Change minter manager and make sure existing controllers still can configure their minters", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+
+ // change minterManager to a new token
+ const newTokenConfig = await initializeTokenWithProxy(rawToken);
+ const newToken = newTokenConfig.token;
+ await newToken.updateMasterMinter(mintController.address, {
+ from: Accounts.tokenOwnerAccount,
+ });
+ await mintController.setMinterManager(newToken.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = newToken.address;
+
+ // now use controller to configure minter
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(10),
+ }
+ );
+ await checkMINTp0(
+ [newToken, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete009 Change minter manager and make sure existing controllers still can remove their minters", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+
+ // change minterManager to a new token
+ const newTokenConfig = await initializeTokenWithProxy(rawToken);
+ const newToken = newTokenConfig.token;
+ await newToken.updateMasterMinter(mintController.address, {
+ from: Accounts.tokenOwnerAccount,
+ });
+ await mintController.setMinterManager(newToken.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = newToken.address;
+
+ // now use controller to configure and remove minter
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [newToken, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete010 Change minter manager and make sure existing controllers can increment allowances", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+
+ // change minterManager to a new token
+ const newTokenConfig = await initializeTokenWithProxy(rawToken);
+ const newToken = newTokenConfig.token;
+ await newToken.updateMasterMinter(mintController.address, {
+ from: Accounts.tokenOwnerAccount,
+ });
+ await mintController.setMinterManager(newToken.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = newToken.address;
+
+ // now use controller to configure minter
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ await mintController.incrementMinterAllowance(20, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(30),
+ }
+ );
+ await checkMINTp0(
+ [newToken, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete011 New controller can increment minter allowance", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(0, {
+ from: Accounts.arbitraryAccount,
+ });
+ await mintController.incrementMinterAllowance(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(10),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete012 New controller can remove minter", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete013 Change minter manager, configure a minter, then change back and make sure changes DID NOT propogate", async function () {
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+
+ // change minterManager to a new token
+ const newTokenConfig = await initializeTokenWithProxy(rawToken);
+ const newToken = newTokenConfig.token;
+ await newToken.updateMasterMinter(mintController.address, {
+ from: Accounts.tokenOwnerAccount,
+ });
+ await mintController.setMinterManager(newToken.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = newToken.address;
+
+ // now use controller to configure minter
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(10),
+ }
+ );
+ await checkMINTp0(
+ [newToken, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+
+ // change minterManager to original token and make sure changes did not propagate
+ await mintController.setMinterManager(token.address, {
+ from: Accounts.mintOwnerAccount,
+ });
+ expectedMintControllerState.minterManager = token.address;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: false },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(0),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete014 Remove a minter and then try to increment its allowance reverts", async function () {
+ // add and remove minter
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+
+ // now verify that incrementing its allowance reverts
+ expectError(
+ mintController.incrementMinterAllowance(20, {
+ from: Accounts.arbitraryAccount,
+ }),
+ "Can only increment allowance for minters in minterManager"
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete015 Configure a minter and make sure it can mint", async function () {
+ // configure a minter
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+
+ // now verify it can mint
+ await token.mint(Accounts.arbitraryAccount, 5, {
+ from: Accounts.minterAccount,
+ });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(5),
+ },
+ {
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: newBigNumber(5),
+ },
+ { variable: "totalSupply", expectedValue: newBigNumber(5) }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete016 Remove a minter and make sure it cannot mint", async function () {
+ // add and remove minter
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+
+ // now verify that minter cannot mint
+ expectRevert(
+ token.mint(Accounts.arbitraryAccount2, 5, {
+ from: Accounts.minterAccount,
+ })
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete017 Configure a minter and make sure it can burn", async function () {
+ // configure a minter
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+
+ // now verify it can burn
+ await token.mint(Accounts.minterAccount, 5, {
+ from: Accounts.minterAccount,
+ });
+ await token.burn(5, { from: Accounts.minterAccount });
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: newBigNumber(5),
+ }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+
+ it("ete018 Remove a minter and make sure it cannot burn", async function () {
+ // add minter, use it to mint to itself, and remove it again
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(10, {
+ from: Accounts.arbitraryAccount,
+ });
+ await token.mint(Accounts.minterAccount, 5, {
+ from: Accounts.minterAccount,
+ });
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount });
+
+ // now verify that minter cannot burn
+ expectRevert(token.burn(5, { from: Accounts.minterAccount }));
+ expectedMintControllerState.controllers.arbitraryAccount =
+ Accounts.minterAccount;
+ expectedTokenState.push(
+ {
+ variable: "balanceAndBlacklistStates.minterAccount",
+ expectedValue: newBigNumber(5),
+ },
+ { variable: "totalSupply", expectedValue: newBigNumber(5) }
+ );
+ await checkMINTp0(
+ [token, mintController],
+ [expectedTokenState, expectedMintControllerState]
+ );
+ });
+}
+
+const wrapTests = require("../v1/helpers/wrapTests");
+wrapTests("MINTp0_EndToEndTests MintController", run_tests_MintController);
+wrapTests("MINTp0_EndToEndTests MasterMinter", run_tests_MasterMinter);
diff --git a/test/minting/MintP0_EventsTests.js b/test/minting/MintP0_EventsTests.js
new file mode 100644
index 000000000..f97016630
--- /dev/null
+++ b/test/minting/MintP0_EventsTests.js
@@ -0,0 +1,344 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const MintController = artifacts.require("minting/MintController");
+const MasterMinter = artifacts.require("minting/MasterMinter");
+
+const mintUtils = require("./MintControllerUtils.js");
+const AccountUtils = require("./AccountUtils.js");
+const Accounts = AccountUtils.Accounts;
+const initializeTokenWithProxyAndMintController =
+ mintUtils.initializeTokenWithProxyAndMintController;
+
+let rawToken;
+let tokenConfig;
+let token;
+let mintController;
+
+const mintControllerEvents = {
+ ownershipTransferred: "OwnershipTransferred",
+ controllerConfigured: "ControllerConfigured",
+ controllerRemoved: "ControllerRemoved",
+ minterManagerSet: "MinterManagerSet",
+ minterCofigured: "MinterConfigured",
+ minterRemoved: "MinterRemoved",
+ minterAllowanceIncremented: "MinterAllowanceIncremented",
+ minterAllowanceDecremented: "MinterAllowanceDecremented",
+};
+
+async function run_tests_MintController(newToken, accounts) {
+ run_MINT_tests(newToken, MintController, accounts);
+}
+
+async function run_tests_MasterMinter(newToken, accounts) {
+ run_MINT_tests(newToken, MasterMinter, accounts);
+}
+
+async function run_MINT_tests(newToken, MintControllerArtifact) {
+ beforeEach("Make fresh token contract", async function () {
+ rawToken = await newToken();
+ tokenConfig = await initializeTokenWithProxyAndMintController(
+ rawToken,
+ MintControllerArtifact
+ );
+ token = tokenConfig.token;
+ mintController = tokenConfig.mintController;
+ });
+
+ it("et100 transferOwnership emits OwnershipTransferred event", async function () {
+ // get all previous transfer ownership events
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.ownershipTransferred,
+ {
+ filter: {
+ previousOwner: Accounts.mintOwnerAccount,
+ newOwner: Accounts.arbitraryAccount,
+ },
+ }
+ );
+
+ // now transfer ownership and test again
+ await mintController.transferOwnership(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.ownershipTransferred,
+ {
+ filter: {
+ previousOwner: Accounts.mintOwnerAccount,
+ newOwner: Accounts.arbitraryAccount,
+ },
+ }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+
+ it("et101 configureController emits ControllerConfigured event", async function () {
+ // get all previous configure controller events
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.controllerConfigured,
+ {
+ filter: {
+ _controller: Accounts.arbitraryAccount,
+ _worker: Accounts.arbitraryAccount2,
+ },
+ }
+ );
+
+ // now configure controller and test again
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.arbitraryAccount2,
+ { from: Accounts.mintOwnerAccount }
+ );
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.controllerConfigured,
+ {
+ filter: {
+ _controller: Accounts.arbitraryAccount,
+ _worker: Accounts.arbitraryAccount2,
+ },
+ }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+
+ it("et102 removeController emits ControllerRemoved event", async function () {
+ // get all previous removeController events
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.arbitraryAccount2,
+ { from: Accounts.mintOwnerAccount }
+ );
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.controllerRemoved,
+ { filter: { _controller: Accounts.arbitraryAccount } }
+ );
+
+ // now remove controller and test again
+ await mintController.removeController(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.controllerRemoved,
+ { filter: { _controller: Accounts.arbitraryAccount } }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+
+ it("et103 setMinterManager emits MinterManagerSet event", async function () {
+ // get all previous set minter manager events
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterManagerSet,
+ {
+ filter: {
+ _oldMinterManager: token.address,
+ _newMinterManager: Accounts.arbitraryAccount,
+ },
+ }
+ );
+
+ // now set minter manager and test again
+ await mintController.setMinterManager(Accounts.arbitraryAccount, {
+ from: Accounts.mintOwnerAccount,
+ });
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterManagerSet,
+ {
+ filter: {
+ _oldMinterManager: token.address,
+ _newMinterManager: Accounts.arbitraryAccount,
+ },
+ }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+
+ it("et104 removeMinter emits MinterRemoved event", async function () {
+ // get all previous remove minter events
+ const allowance = 10;
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(allowance, {
+ from: Accounts.arbitraryAccount,
+ });
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterRemoved,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ },
+ }
+ );
+
+ // now remove minter and test again
+ await mintController.removeMinter({ from: Accounts.arbitraryAccount });
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterRemoved,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ },
+ }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+
+ it("et105 configureMinter emits MinterConfigured event", async function () {
+ // get all previous configureMinter events
+ const allowance = 10;
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterCofigured,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ _allowance: allowance,
+ },
+ }
+ );
+
+ // now transfer ownership and test again
+ await mintController.configureMinter(allowance, {
+ from: Accounts.arbitraryAccount,
+ });
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterCofigured,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ _allowance: allowance,
+ },
+ }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+
+ it("et106 incrementMinterAllowance emits MinterAllowanceIncremented event", async function () {
+ // get all previous increment minter allowance events
+ const allowance = 10;
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(allowance, {
+ from: Accounts.arbitraryAccount,
+ });
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterAllowanceIncremented,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ _increment: allowance,
+ _newAllowance: allowance * 2,
+ },
+ }
+ );
+
+ // now increment minter allowance and test again
+ await mintController.incrementMinterAllowance(allowance, {
+ from: Accounts.arbitraryAccount,
+ });
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterAllowanceIncremented,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ _increment: allowance,
+ _newAllowance: allowance * 2,
+ },
+ }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+
+ it("et107 decrementMinterAllowance emits MinterAllowanceDecremented event", async function () {
+ // get all previous decrement minter allowance events
+ const allowance = 10;
+ await mintController.configureController(
+ Accounts.arbitraryAccount,
+ Accounts.minterAccount,
+ { from: Accounts.mintOwnerAccount }
+ );
+ await mintController.configureMinter(allowance, {
+ from: Accounts.arbitraryAccount,
+ });
+ const preEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterAllowanceDecremented,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ _decrement: allowance,
+ _newAllowance: 0,
+ },
+ }
+ );
+
+ // now decrement minter allowance and test again
+ await mintController.decrementMinterAllowance(allowance, {
+ from: Accounts.arbitraryAccount,
+ });
+ const postEvents = await mintController.getPastEvents(
+ mintControllerEvents.minterAllowanceDecremented,
+ {
+ filter: {
+ _msgSender: Accounts.arbitraryAccount,
+ _minter: Accounts.minterAccount,
+ _decrement: allowance,
+ _newAllowance: 0,
+ },
+ }
+ );
+
+ // one new event must have fired
+ assert.equal(preEvents.length + 1, postEvents.length);
+ });
+}
+
+const wrapTests = require("../v1/helpers/wrapTests");
+wrapTests("MINTp0_EventTests MintController", run_tests_MintController);
+wrapTests("MINTp0_EventTests MasterMinter", run_tests_MasterMinter);
diff --git a/test/misc/gas.ts b/test/misc/gas.ts
new file mode 100644
index 000000000..d9de62269
--- /dev/null
+++ b/test/misc/gas.ts
@@ -0,0 +1,325 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ AnyFiatTokenV2Instance,
+ FiatTokenV2_2InstanceExtended,
+} from "../../@types/AnyFiatTokenV2Instance";
+import {
+ FiatTokenV2_1Contract,
+ FiatTokenV2_2Contract,
+} from "../../@types/generated";
+import { AllEvents } from "../../@types/generated/FiatTokenV2";
+import { initializeToVersion, linkLibraryToTokenContract } from "../helpers";
+import {
+ HARDHAT_ACCOUNTS,
+ HARDHAT_PRIVATE_KEYS,
+ MAX_UINT256_HEX,
+} from "../helpers/constants";
+import {
+ SignatureBytesType,
+ permitSignature,
+ permitSignatureV22,
+ prepareSignature,
+ signPermit,
+} from "../v2/GasAbstraction/helpers";
+import { getERC1271Wallet } from "../v2/v2.behavior";
+
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+const FiatTokenV2_2 = artifacts.require("FiatTokenV2_2");
+
+type TestVersion = "2.1" | "2.2";
+// can be changed in case of upgrade
+const TARGET_VERSION = "2.2";
+type TestContract = FiatTokenV2_1Contract | FiatTokenV2_2Contract;
+
+const versionToContract = new Map([
+ ["2.1", FiatTokenV2_1],
+ ["2.2", FiatTokenV2_2],
+]);
+const consoleMessage = "gas used for the test below:";
+
+describe(`gas costs for version ${TARGET_VERSION}`, () => {
+ const lostAndFound = HARDHAT_ACCOUNTS[2];
+ const alice = HARDHAT_ACCOUNTS[3];
+ const aliceKey = HARDHAT_PRIVATE_KEYS[3];
+ const bob = HARDHAT_ACCOUNTS[4];
+ const charlie = HARDHAT_ACCOUNTS[5];
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[9];
+ const entireBalance = 100;
+ const partialBalance = 1;
+ const mintAuthorizationAmount = 10000;
+
+ let fiatToken: AnyFiatTokenV2Instance;
+ let domainSeparator: string;
+ let contractTarget: TestContract;
+
+ async function mintBalance(
+ account: string
+ ): Promise> {
+ return fiatToken.mint(account, entireBalance, { from: fiatTokenOwner });
+ }
+
+ before(async () => {
+ if (!versionToContract.get(TARGET_VERSION))
+ throw new Error("invalid version");
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ contractTarget = versionToContract.get(TARGET_VERSION)!;
+
+ // NOTE: need to add a new version here if there is an upgrade
+ // beyond 2.2
+ await linkLibraryToTokenContract(FiatTokenV2_1);
+ await linkLibraryToTokenContract(FiatTokenV2_2);
+ });
+
+ beforeEach(async () => {
+ fiatToken = await contractTarget.new();
+ await initializeToVersion(
+ fiatToken,
+ TARGET_VERSION,
+ fiatTokenOwner,
+ lostAndFound
+ );
+ await fiatToken.configureMinter(fiatTokenOwner, mintAuthorizationAmount, {
+ from: fiatTokenOwner,
+ });
+
+ // mint to fiat token owner to initialize total supply
+ await mintBalance(fiatTokenOwner);
+
+ domainSeparator = await fiatToken.DOMAIN_SEPARATOR();
+ });
+
+ it("mint() where the receiver has no balance", async () => {
+ const tx = await mintBalance(bob);
+
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("mint() where the receiver has an existing balance", async () => {
+ await mintBalance(bob);
+
+ const tx = await mintBalance(bob);
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("burn() entire balance", async () => {
+ const tx = await fiatToken.burn(entireBalance, { from: fiatTokenOwner });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("burn() partial balance", async () => {
+ const tx = await fiatToken.burn(partialBalance, { from: fiatTokenOwner });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transfer() where both parties have a balance before and after", async () => {
+ await mintBalance(alice);
+ await mintBalance(bob);
+
+ const tx = await fiatToken.transfer(bob, partialBalance, {
+ from: alice,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transfer() where sender transfers their entire balance, receiver has a balance", async () => {
+ await mintBalance(alice);
+ await mintBalance(bob);
+
+ const tx = await fiatToken.transfer(bob, entireBalance, {
+ from: alice,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transfer() where sender transfers their entire balance, receiver has no balance", async () => {
+ await mintBalance(bob);
+
+ const tx = await fiatToken.transfer(alice, entireBalance, {
+ from: bob,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transfer() where sender transfers part of their balance, receiver has no balance", async () => {
+ await mintBalance(alice);
+
+ const tx = await fiatToken.transfer(bob, partialBalance, {
+ from: alice,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transferFrom() where both parties have a balance before and after", async () => {
+ await mintBalance(alice);
+ await mintBalance(bob);
+
+ await fiatToken.approve(bob, entireBalance, { from: alice });
+
+ const tx = await fiatToken.transferFrom(alice, bob, partialBalance, {
+ from: bob,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transferFrom() where sender transfers their entire balance, receiver has a balance", async () => {
+ await mintBalance(alice);
+ await mintBalance(bob);
+
+ await fiatToken.approve(bob, entireBalance, { from: alice });
+
+ const tx = await fiatToken.transferFrom(alice, bob, entireBalance, {
+ from: bob,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transferFrom() where sender transfers their entire balance, receiver has no balance", async () => {
+ await mintBalance(alice);
+
+ await fiatToken.approve(bob, entireBalance, { from: alice });
+
+ const tx = await fiatToken.transferFrom(alice, bob, entireBalance, {
+ from: bob,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("transferFrom() where sender transfers part of their balance, receiver has no balance", async () => {
+ await mintBalance(alice);
+
+ await fiatToken.approve(bob, entireBalance, { from: alice });
+
+ const tx = await fiatToken.transferFrom(alice, bob, partialBalance, {
+ from: bob,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("approve()", async () => {
+ const tx = await fiatToken.approve(bob, entireBalance, { from: alice });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("increaseAllowance() with no prior approval", async () => {
+ const tx = await fiatToken.increaseAllowance(bob, entireBalance, {
+ from: alice,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("increaseAllowance() on existing approval", async () => {
+ await fiatToken.approve(bob, entireBalance, { from: alice });
+
+ const tx = await fiatToken.increaseAllowance(bob, entireBalance, {
+ from: alice,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("decreaseAllowance() to zero", async () => {
+ await fiatToken.approve(bob, entireBalance, { from: alice });
+
+ const tx = await fiatToken.decreaseAllowance(bob, entireBalance, {
+ from: alice,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("decreaseAllowance() to non-zero", async () => {
+ await fiatToken.approve(bob, entireBalance, { from: alice });
+
+ const tx = await fiatToken.decreaseAllowance(bob, partialBalance, {
+ from: alice,
+ });
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("permit() with an EOA", async () => {
+ const nonce = 0;
+ const deadline = MAX_UINT256_HEX;
+ const signatureType = SignatureBytesType.Unpacked;
+
+ // permit() is overloaded as of 2.2, so we need to specify which permit()
+ // version to hit. In this case, the EOA version.
+ if (Number(TARGET_VERSION) >= 2.2) {
+ (fiatToken as FiatTokenV2_2InstanceExtended).permit = (fiatToken as FiatTokenV2_2InstanceExtended).methods[
+ permitSignature
+ ];
+ }
+
+ const signature = signPermit(
+ alice,
+ bob,
+ entireBalance,
+ nonce,
+ deadline,
+ domainSeparator,
+ aliceKey
+ );
+ const tx = await fiatToken.permit(
+ alice,
+ bob,
+ entireBalance,
+ deadline,
+ ...prepareSignature(signature, signatureType),
+ { from: charlie }
+ );
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+
+ it("permit() with an EIP-1271 wallet", async () => {
+ const nonce = 0;
+ const deadline = MAX_UINT256_HEX;
+ const signatureType = SignatureBytesType.Packed;
+ const aliceWallet = await getERC1271Wallet(alice);
+
+ if (Number(TARGET_VERSION) < 2.2) {
+ console.log("Test below not relevant for this contract version");
+ return;
+ }
+
+ // permit() is overloaded as of 2.2, so we need to specify which permit()
+ // version to hit. In this case, the EIP-1271 version.
+ {
+ (fiatToken as FiatTokenV2_2InstanceExtended).permit = (fiatToken as FiatTokenV2_2InstanceExtended).methods[
+ permitSignatureV22
+ ];
+ }
+
+ const signature = signPermit(
+ aliceWallet.address,
+ bob,
+ entireBalance,
+ nonce,
+ deadline,
+ domainSeparator,
+ aliceKey
+ );
+ const tx = await fiatToken.permit(
+ aliceWallet.address,
+ bob,
+ entireBalance,
+ deadline,
+ ...prepareSignature(signature, signatureType),
+ { from: charlie }
+ );
+ console.log(consoleMessage, tx.receipt.gasUsed);
+ });
+});
diff --git a/test/misc/publicToExternal.test.ts b/test/misc/publicToExternal.test.ts
index 31e91a1a4..9f604050b 100644
--- a/test/misc/publicToExternal.test.ts
+++ b/test/misc/publicToExternal.test.ts
@@ -1,8 +1,27 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import {
ContractWithPublicFunctionsInstance,
ContractWithExternalFunctionsInstance,
ContractThatCallsPublicFunctionsInstance,
} from "../../@types/generated";
+import { HARDHAT_ACCOUNTS } from "../helpers/constants";
const ContractWithPublicFunctions = artifacts.require(
"ContractWithPublicFunctions"
@@ -15,8 +34,10 @@ const ContractThatCallsPublicFunctions = artifacts.require(
);
const FiatTokenProxy = artifacts.require("FiatTokenProxy");
-contract("public to external", (accounts) => {
+describe("public to external", () => {
describe("changing access modifier from public to external", () => {
+ const from = HARDHAT_ACCOUNTS[0];
+
let contractWithPublicFunctions: ContractWithPublicFunctionsInstance;
let contractWithExternalFunctions: ContractWithExternalFunctionsInstance;
let contractThatCallsPublicFunctions: ContractThatCallsPublicFunctionsInstance;
@@ -58,7 +79,7 @@ contract("public to external", (accounts) => {
// functions
const proxy = await FiatTokenProxy.new(
contractWithPublicFunctions.address,
- { from: accounts[0] }
+ { from }
);
// verify that calling public functions via the proxy works fine
diff --git a/test/scripts/deploy/TestUtils.sol b/test/scripts/deploy/TestUtils.sol
new file mode 100644
index 000000000..36b78617a
--- /dev/null
+++ b/test/scripts/deploy/TestUtils.sol
@@ -0,0 +1,155 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376
+
+import "forge-std/Test.sol"; // solhint-disable no-global-import
+import { MasterMinter } from "../../../contracts/minting/MasterMinter.sol";
+import { FiatTokenProxy } from "../../../contracts/v1/FiatTokenProxy.sol";
+import { FiatTokenV2_2 } from "../../../contracts/v2/FiatTokenV2_2.sol";
+import {
+ AbstractV2Upgrader
+} from "../../../contracts/v2/upgrader/AbstractV2Upgrader.sol";
+import {
+ FiatTokenCeloV2_2
+} from "../../../contracts/v2/celo/FiatTokenCeloV2_2.sol";
+
+contract TestUtils is Test {
+ uint256 internal deployerPrivateKey = 1;
+ uint256 internal proxyAdminPrivateKey = 2;
+ uint256 internal masterMinterOwnerPrivateKey = 3;
+ uint256 internal ownerPrivateKey = 4;
+ uint256 internal pauserPrivateKey = 5;
+ uint256 internal blacklisterPrivateKey = 6;
+
+ address internal deployer = vm.addr(deployerPrivateKey);
+ address internal proxyAdmin = vm.addr(proxyAdminPrivateKey);
+ address internal masterMinterOwner = vm.addr(masterMinterOwnerPrivateKey);
+ address internal owner = vm.addr(ownerPrivateKey);
+ address internal pauser = vm.addr(pauserPrivateKey);
+ address internal blacklister = vm.addr(blacklisterPrivateKey);
+
+ uint8 internal decimals = 6;
+ string internal tokenName = "USDC";
+ string internal tokenSymbol = "USDC";
+ string internal tokenCurrency = "USD";
+
+ string internal blacklistFileName = "test.blacklist.remote.json";
+
+ address[] internal accountsToBlacklist = [
+ 0x04DBA1194ee10112fE6C3207C0687DEf0e78baCf,
+ 0xb6f5ec1A0a9cd1526536D3F0426c429529471F40
+ ];
+
+ function setUp() public virtual {
+ vm.setEnv("TOKEN_NAME", tokenName);
+ vm.setEnv("TOKEN_SYMBOL", tokenSymbol);
+ vm.setEnv("TOKEN_CURRENCY", tokenCurrency);
+ vm.setEnv("TOKEN_DECIMALS", "6");
+ vm.setEnv("DEPLOYER_PRIVATE_KEY", vm.toString(deployerPrivateKey));
+ vm.setEnv("PROXY_ADMIN_ADDRESS", vm.toString(proxyAdmin));
+ vm.setEnv(
+ "MASTER_MINTER_OWNER_ADDRESS",
+ vm.toString(masterMinterOwner)
+ );
+ vm.setEnv("OWNER_ADDRESS", vm.toString(owner));
+ vm.setEnv("PAUSER_ADDRESS", vm.toString(pauser));
+ vm.setEnv("BLACKLISTER_ADDRESS", vm.toString(blacklister));
+
+ // Deploy an instance of proxy contract to configure contract address in env
+ vm.prank(deployer);
+ FiatTokenV2_2 v2_2 = new FiatTokenV2_2();
+
+ vm.prank(proxyAdmin);
+ FiatTokenProxy proxy = new FiatTokenProxy(address(v2_2));
+
+ vm.startPrank(deployer);
+ MasterMinter masterMinter = new MasterMinter(address(proxy));
+ masterMinter.transferOwnership(masterMinterOwner);
+
+ FiatTokenV2_2 proxyAsV2_2 = FiatTokenV2_2(address(proxy));
+
+ proxyAsV2_2.initialize(
+ tokenName,
+ tokenSymbol,
+ "USD",
+ decimals,
+ address(masterMinter),
+ pauser,
+ blacklister,
+ vm.addr(ownerPrivateKey)
+ );
+ proxyAsV2_2.initializeV2(tokenName);
+ proxyAsV2_2.initializeV2_1(owner);
+ proxyAsV2_2.initializeV2_2(new address[](0), tokenSymbol);
+ vm.setEnv("FIAT_TOKEN_PROXY_ADDRESS", vm.toString(address(proxy)));
+
+ vm.setEnv("BLACKLIST_FILE_NAME", blacklistFileName);
+
+ setUpCelo();
+ }
+
+ function setUpCelo() internal {
+ // Deploy and initialize FiatTokenCeloV2_2 and it's proxy.
+ vm.startPrank(deployer);
+ FiatTokenCeloV2_2 celoV2_2 = new FiatTokenCeloV2_2();
+ FiatTokenProxy proxy = new FiatTokenProxy(address(celoV2_2));
+ FiatTokenCeloV2_2 proxyAsV2_2 = FiatTokenCeloV2_2(address(proxy));
+ MasterMinter masterMinter = new MasterMinter(address(proxy));
+ masterMinter.transferOwnership(masterMinterOwner);
+ proxy.changeAdmin(proxyAdmin);
+ // This is required since the FiatTokenFeeAdapter needs the decimals field.
+ proxyAsV2_2.initialize(
+ tokenName,
+ tokenSymbol,
+ tokenCurrency,
+ decimals,
+ address(masterMinter),
+ pauser,
+ blacklister,
+ owner
+ );
+ proxyAsV2_2.initializeV2(tokenName);
+ proxyAsV2_2.initializeV2_1(owner);
+ proxyAsV2_2.initializeV2_2(new address[](0), tokenSymbol);
+ vm.stopPrank();
+
+ vm.setEnv("FIAT_TOKEN_CELO_PROXY_ADDRESS", vm.toString(address(proxy)));
+ vm.setEnv("FEE_ADAPTER_PROXY_ADMIN_ADDRESS", vm.toString(proxyAdmin));
+ vm.setEnv("FEE_ADAPTER_DECIMALS", "18");
+ }
+
+ function validateImpl(FiatTokenV2_2 impl) internal {
+ assertEq(impl.name(), "");
+ assertEq(impl.symbol(), "");
+ assertEq(impl.currency(), "");
+ assert(impl.decimals() == 0);
+ assertEq(impl.owner(), address(1));
+ assertEq(impl.masterMinter(), address(1));
+ assertEq(impl.pauser(), address(1));
+ assertEq(impl.blacklister(), address(1));
+ }
+
+ function validateMasterMinter(MasterMinter masterMinter, address _proxy)
+ internal
+ {
+ assertEq(masterMinter.owner(), masterMinterOwner);
+ assertEq(address(masterMinter.getMinterManager()), _proxy);
+ }
+}
diff --git a/test/scripts/deploy/celo/deploy-fee-adapter.t.sol b/test/scripts/deploy/celo/deploy-fee-adapter.t.sol
new file mode 100644
index 000000000..38b1de2b4
--- /dev/null
+++ b/test/scripts/deploy/celo/deploy-fee-adapter.t.sol
@@ -0,0 +1,83 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376
+
+import { TestUtils } from "./../TestUtils.sol";
+import {
+ DeployFiatToken
+} from "../../../../scripts/deploy/deploy-fiat-token.s.sol";
+import {
+ DeployFeeAdapter
+} from "../../../../scripts/deploy/celo/deploy-fee-adapter.s.sol";
+
+import { FiatTokenProxy } from "../../../../contracts/v1/FiatTokenProxy.sol";
+import { FiatTokenV2_2 } from "../../../../contracts/v2/FiatTokenV2_2.sol";
+import {
+ FiatTokenCeloV2_2
+} from "../../../../contracts/v2/celo/FiatTokenCeloV2_2.sol";
+import {
+ FiatTokenFeeAdapterProxy
+} from "../../../../contracts/v2/celo/FiatTokenFeeAdapterProxy.sol";
+import {
+ FiatTokenFeeAdapterV1
+} from "../../../../contracts/v2/celo/FiatTokenFeeAdapterV1.sol";
+import { MasterMinter } from "../../../../contracts/minting/MasterMinter.sol";
+
+// solhint-disable func-name-mixedcase
+
+contract DeployFeeAdapterTest is TestUtils {
+ DeployFeeAdapter private deployScript;
+
+ function setUp() public override {
+ TestUtils.setUp();
+
+ vm.prank(deployer);
+ deployScript = new DeployFeeAdapter();
+ deployScript.setUp();
+ }
+
+ function test_deployFeeAdapter() public {
+ (
+ FiatTokenFeeAdapterV1 v1,
+ FiatTokenFeeAdapterProxy proxy
+ ) = deployScript.run();
+
+ validateImpl(v1);
+ validateProxy(proxy, address(v1));
+ }
+
+ function validateImpl(FiatTokenFeeAdapterV1 impl) internal {
+ assert(impl.adapterDecimals() == 18);
+ assert(impl.tokenDecimals() == 6);
+ assert(impl.upscaleFactor() == 1000000000000);
+ }
+
+ function validateProxy(FiatTokenFeeAdapterProxy proxy, address impl)
+ internal
+ {
+ assertEq(proxy.admin(), proxyAdmin);
+ assertEq(proxy.implementation(), impl);
+
+ FiatTokenFeeAdapterV1 proxyAsV1 = FiatTokenFeeAdapterV1(address(proxy));
+ assert(proxyAsV1.adapterDecimals() == 18);
+ assert(proxyAsV1.tokenDecimals() == 6);
+ assert(proxyAsV1.upscaleFactor() == 1000000000000);
+ }
+}
diff --git a/test/scripts/deploy/celo/deploy-fiat-token-celo.t.sol b/test/scripts/deploy/celo/deploy-fiat-token-celo.t.sol
new file mode 100644
index 000000000..a235c5dc0
--- /dev/null
+++ b/test/scripts/deploy/celo/deploy-fiat-token-celo.t.sol
@@ -0,0 +1,86 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376
+
+import { TestUtils } from "./../TestUtils.sol";
+import {
+ DeployFiatTokenCelo
+} from "../../../../scripts/deploy/celo/deploy-fiat-token-celo.s.sol";
+import { MasterMinter } from "../../../../contracts/minting/MasterMinter.sol";
+import { FiatTokenProxy } from "../../../../contracts/v1/FiatTokenProxy.sol";
+import {
+ FiatTokenCeloV2_2
+} from "../../../../contracts/v2/celo/FiatTokenCeloV2_2.sol";
+
+// solhint-disable func-name-mixedcase
+
+contract DeployFiatTokenCeloTest is TestUtils {
+ DeployFiatTokenCelo private deployScript;
+
+ function setUp() public override {
+ TestUtils.setUp();
+
+ vm.prank(deployer);
+ deployScript = new DeployFiatTokenCelo();
+ deployScript.setUp();
+ }
+
+ function test_deployFiatTokenWithEnvConfigured() public {
+ (
+ FiatTokenCeloV2_2 v2_2,
+ MasterMinter masterMinter,
+ FiatTokenProxy proxy
+ ) = deployScript.run();
+
+ validateImpl(v2_2);
+ validateMasterMinter(masterMinter, address(proxy));
+ validateProxy(proxy, address(v2_2), address(masterMinter));
+ }
+
+ function test_deployFiatTokenWithPredeployedImpl() public {
+ vm.prank(deployer);
+ FiatTokenCeloV2_2 predeployedImpl = new FiatTokenCeloV2_2();
+
+ (, MasterMinter masterMinter, FiatTokenProxy proxy) = deployScript
+ .deploy(address(predeployedImpl));
+
+ validateMasterMinter(masterMinter, address(proxy));
+ validateProxy(proxy, address(predeployedImpl), address(masterMinter));
+ }
+
+ function validateProxy(
+ FiatTokenProxy proxy,
+ address _impl,
+ address _masterMinter
+ ) internal {
+ assertEq(proxy.admin(), proxyAdmin);
+ assertEq(proxy.implementation(), _impl);
+
+ FiatTokenCeloV2_2 proxyAsV2_2 = FiatTokenCeloV2_2(address(proxy));
+ assertEq(proxyAsV2_2.name(), "USDC");
+ assertEq(proxyAsV2_2.symbol(), "USDC");
+ assertEq(proxyAsV2_2.currency(), "USD");
+ assert(proxyAsV2_2.decimals() == 6);
+ assertEq(proxyAsV2_2.owner(), owner);
+ assertEq(proxyAsV2_2.pauser(), pauser);
+ assertEq(proxyAsV2_2.blacklister(), blacklister);
+ assertEq(proxyAsV2_2.masterMinter(), _masterMinter);
+ }
+}
diff --git a/test/scripts/deploy/deploy-fiat-token.t.sol b/test/scripts/deploy/deploy-fiat-token.t.sol
new file mode 100644
index 000000000..58d260b2f
--- /dev/null
+++ b/test/scripts/deploy/deploy-fiat-token.t.sol
@@ -0,0 +1,84 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376
+
+import { TestUtils } from "./TestUtils.sol";
+import {
+ DeployFiatToken
+} from "../../../scripts/deploy/deploy-fiat-token.s.sol";
+import { MasterMinter } from "../../../contracts/minting/MasterMinter.sol";
+import { FiatTokenProxy } from "../../../contracts/v1/FiatTokenProxy.sol";
+import { FiatTokenV2_2 } from "../../../contracts/v2/FiatTokenV2_2.sol";
+
+// solhint-disable func-name-mixedcase
+
+contract DeployFiatTokenTest is TestUtils {
+ DeployFiatToken private deployScript;
+
+ function setUp() public override {
+ TestUtils.setUp();
+
+ vm.prank(deployer);
+ deployScript = new DeployFiatToken();
+ deployScript.setUp();
+ }
+
+ function test_deployFiatTokenWithEnvConfigured() public {
+ (
+ FiatTokenV2_2 v2_2,
+ MasterMinter masterMinter,
+ FiatTokenProxy proxy
+ ) = deployScript.run();
+
+ validateImpl(v2_2);
+ validateMasterMinter(masterMinter, address(proxy));
+ validateProxy(proxy, address(v2_2), address(masterMinter));
+ }
+
+ function test_deployFiatTokenWithPredeployedImpl() public {
+ vm.prank(deployer);
+ FiatTokenV2_2 predeployedImpl = new FiatTokenV2_2();
+
+ (, MasterMinter masterMinter, FiatTokenProxy proxy) = deployScript
+ .deploy(address(predeployedImpl));
+
+ validateMasterMinter(masterMinter, address(proxy));
+ validateProxy(proxy, address(predeployedImpl), address(masterMinter));
+ }
+
+ function validateProxy(
+ FiatTokenProxy proxy,
+ address _impl,
+ address _masterMinter
+ ) internal {
+ assertEq(proxy.admin(), proxyAdmin);
+ assertEq(proxy.implementation(), _impl);
+
+ FiatTokenV2_2 proxyAsV2_2 = FiatTokenV2_2(address(proxy));
+ assertEq(proxyAsV2_2.name(), "USDC");
+ assertEq(proxyAsV2_2.symbol(), "USDC");
+ assertEq(proxyAsV2_2.currency(), "USD");
+ assert(proxyAsV2_2.decimals() == 6);
+ assertEq(proxyAsV2_2.owner(), owner);
+ assertEq(proxyAsV2_2.pauser(), pauser);
+ assertEq(proxyAsV2_2.blacklister(), blacklister);
+ assertEq(proxyAsV2_2.masterMinter(), _masterMinter);
+ }
+}
diff --git a/test/scripts/deploy/deploy-impl-and-upgrader.t.sol b/test/scripts/deploy/deploy-impl-and-upgrader.t.sol
new file mode 100644
index 000000000..a1ebe9936
--- /dev/null
+++ b/test/scripts/deploy/deploy-impl-and-upgrader.t.sol
@@ -0,0 +1,79 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376
+
+import { TestUtils } from "./TestUtils.sol";
+import {
+ DeployImplAndUpgrader
+} from "../../../scripts/deploy/deploy-impl-and-upgrader.s.sol";
+import { FiatTokenV2_2 } from "../../../contracts/v2/FiatTokenV2_2.sol";
+import { V2_2Upgrader } from "../../../contracts/v2/upgrader/V2_2Upgrader.sol";
+
+// solhint-disable func-name-mixedcase
+
+contract DeployImplAndUpgraderTest is TestUtils {
+ DeployImplAndUpgrader private deployScript;
+
+ function setUp() public override {
+ TestUtils.setUp();
+
+ vm.prank(deployer);
+ deployScript = new DeployImplAndUpgrader();
+ deployScript.setUp();
+ }
+
+ function test_DeployImplAndUpgraderWithAllEnvConfigured() public {
+ (FiatTokenV2_2 v2_2, V2_2Upgrader upgrader) = deployScript.run();
+
+ validateImpl(v2_2);
+ validateUpgrader(
+ upgrader,
+ vm.envAddress("FIAT_TOKEN_PROXY_ADDRESS"),
+ address(v2_2)
+ );
+ }
+
+ function test_DeployImplAndUpgraderWithPredeployedImpl() public {
+ vm.prank(deployer);
+ FiatTokenV2_2 predeployedImpl = new FiatTokenV2_2();
+
+ (, V2_2Upgrader upgrader) = deployScript.deploy(
+ address(predeployedImpl)
+ );
+
+ validateUpgrader(
+ upgrader,
+ vm.envAddress("FIAT_TOKEN_PROXY_ADDRESS"),
+ address(predeployedImpl)
+ );
+ }
+
+ function validateUpgrader(
+ V2_2Upgrader upgrader,
+ address proxy,
+ address impl
+ ) internal {
+ assertEq(upgrader.implementation(), impl);
+ assertEq(upgrader.proxy(), proxy);
+ assertEq(upgrader.newProxyAdmin(), proxyAdmin);
+ assertEq(upgrader.owner(), vm.addr(deployerPrivateKey));
+ assertEq(upgrader.accountsToBlacklist(), accountsToBlacklist);
+ }
+}
diff --git a/test/scripts/deploy/deploy-master-minter.t.sol b/test/scripts/deploy/deploy-master-minter.t.sol
new file mode 100644
index 000000000..b1594966a
--- /dev/null
+++ b/test/scripts/deploy/deploy-master-minter.t.sol
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2; // needed for compiling older solc versions: https://github.com/foundry-rs/foundry/issues/4376
+
+import { TestUtils } from "./TestUtils.sol";
+import {
+ DeployMasterMinter
+} from "../../../scripts/deploy/deploy-master-minter.s.sol";
+import { MasterMinter } from "../../../contracts/minting/MasterMinter.sol";
+
+// solhint-disable func-name-mixedcase
+
+contract DeployMasterMinterTest is TestUtils {
+ DeployMasterMinter internal deployScript;
+
+ function setUp() public override {
+ TestUtils.setUp();
+
+ vm.prank(deployer);
+ deployScript = new DeployMasterMinter();
+ deployScript.setUp();
+ }
+
+ function test_deployMasterMinter() public {
+ MasterMinter masterMinter = deployScript.run();
+
+ validateMasterMinter(
+ masterMinter,
+ vm.envAddress("FIAT_TOKEN_PROXY_ADDRESS")
+ );
+ }
+}
diff --git a/test/scripts/hardhat/testData/FiatTokenProxy.bin b/test/scripts/hardhat/testData/FiatTokenProxy.bin
new file mode 100644
index 000000000..51385135d
--- /dev/null
+++ b/test/scripts/hardhat/testData/FiatTokenProxy.bin
@@ -0,0 +1 @@
+0x60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146101315780638f2839701461016f578063f851a440146101af5761005a565b80633659cfe6146100645780634f1ef286146100a4575b6100626101c4565b005b34801561007057600080fd5b506100626004803603602081101561008757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101de565b610062600480360360408110156100ba57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156100f257600080fd5b82018360208201111561010457600080fd5b8035906020019184600183028401116401000000008311171561012657600080fd5b509092509050610232565b34801561013d57600080fd5b50610146610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561017b57600080fd5b506100626004803603602081101561019257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610318565b3480156101bb57600080fd5b50610146610420565b6101cc610430565b6101dc6101d76104c4565b6104e9565b565b6101e661050d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275761022281610532565b61022f565b61022f6101c4565b50565b61023a61050d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fc5761027683610532565b60003073ffffffffffffffffffffffffffffffffffffffff16348484604051808383808284376040519201945060009350909150508083038185875af1925050503d80600081146102e3576040519150601f19603f3d011682016040523d82523d6000602084013e6102e8565b606091505b50509050806102f657600080fd5b50610304565b6103046101c4565b505050565b60006103136104c4565b905090565b61032061050d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102275773ffffffffffffffffffffffffffffffffffffffff81166103bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806106606036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103e861050d565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a161022281610587565b600061031361050d565b3b151590565b61043861050d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156104bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603281526020018061062e6032913960400191505060405180910390fd5b6101dc6101dc565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e808015610508573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b61053b816105ab565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b6105b48161042a565b610609576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180610696603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a26469706673582212206f00cbbebd342a531f03db15fd5aaf4b2dc16ecb732f35d416c34bfb2649860764736f6c634300060c0033
\ No newline at end of file
diff --git a/test/scripts/hardhat/testData/FiatTokenProxy.metadata.json b/test/scripts/hardhat/testData/FiatTokenProxy.metadata.json
new file mode 100644
index 000000000..f0d74ee12
--- /dev/null
+++ b/test/scripts/hardhat/testData/FiatTokenProxy.metadata.json
@@ -0,0 +1,231 @@
+{
+ "compiler": {
+ "version": "0.6.12+commit.27d51765"
+ },
+ "language": "Solidity",
+ "output": {
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementationContract",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address",
+ "indexed": false
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address",
+ "indexed": false
+ }
+ ],
+ "type": "event",
+ "name": "AdminChanged",
+ "anonymous": false
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address",
+ "indexed": false
+ }
+ ],
+ "type": "event",
+ "name": "Upgraded",
+ "anonymous": false
+ },
+ {
+ "inputs": [],
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "stateMutability": "view",
+ "type": "function",
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ]
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function",
+ "name": "changeAdmin"
+ },
+ {
+ "inputs": [],
+ "stateMutability": "view",
+ "type": "function",
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ]
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function",
+ "name": "upgradeTo"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "function",
+ "name": "upgradeToAndCall"
+ }
+ ],
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "returns": {
+ "_0": "The address of the proxy admin."
+ }
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Only the current admin can call this function.",
+ "params": {
+ "newAdmin": "Address to transfer proxy administration to."
+ }
+ },
+ "implementation()": {
+ "returns": {
+ "_0": "The address of the implementation."
+ }
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the backing implementation of the proxy. Only the admin can call this function.",
+ "params": {
+ "newImplementation": "Address of the new implementation."
+ }
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the backing implementation of the proxy and call a function on the new implementation. This is useful to initialize the proxied contract.",
+ "params": {
+ "data": "Data to send as msg.data in the low level call. It should include the signature and the parameters of the function to be called, as described in https://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector-and-argument-encoding.",
+ "newImplementation": "Address of the new implementation."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ }
+ },
+ "settings": {
+ "remappings": [
+ "@ensdomains/=node_modules/@ensdomains/",
+ "@openzeppelin/=node_modules/@openzeppelin/",
+ "@solidity-parser/=node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/",
+ "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/"
+ ],
+ "optimizer": {
+ "enabled": true,
+ "runs": 10000000
+ },
+ "metadata": {
+ "bytecodeHash": "ipfs"
+ },
+ "compilationTarget": {
+ "contracts/v1/FiatTokenProxy.sol": "FiatTokenProxy"
+ },
+ "evmVersion": "istanbul",
+ "libraries": {}
+ },
+ "sources": {
+ "contracts/upgradeability/AdminUpgradeabilityProxy.sol": {
+ "keccak256": "0x709d23a3d4b34a43861d099ec8c3f964c933f45bf30ee08c98a569433114c599",
+ "urls": [
+ "bzz-raw://97ec753a4c2cf21c11daccde7727b3343bedfe985b7299ddb86b91b641c6bb8e",
+ "dweb:/ipfs/QmRerVbjv74Yx4Pa26am82cAMDyMXzka1oE9YnrQtGwkd7"
+ ],
+ "license": "Apache-2.0"
+ },
+ "contracts/upgradeability/Proxy.sol": {
+ "keccak256": "0x27eb2c0719a143aafc9f7f1fa39ef225baa0ad667bcd5f90cd1e4abcc89f4c20",
+ "urls": [
+ "bzz-raw://90cc41dbda5503142c6742a0b88fac18b9738dab7fb47365f9dd004921c31357",
+ "dweb:/ipfs/QmUfVsoFGj4nKvEy5fx7yszqNbC9VXWWkfWfMBHcwouLqr"
+ ],
+ "license": "Apache-2.0"
+ },
+ "contracts/upgradeability/UpgradeabilityProxy.sol": {
+ "keccak256": "0xa7a9d804acfb476666548a05cd94ce8a5ffa6bd76b038cbc3f1683d6ac708c49",
+ "urls": [
+ "bzz-raw://805cbc090ff93c9d6eb6348683c6d2cf5da46c2bca254fda8d87516d395f9299",
+ "dweb:/ipfs/Qmez8Q656MWiJwHw2t88X6bJwgbK2aUnnoqcj2FzyaWxdy"
+ ],
+ "license": "Apache-2.0"
+ },
+ "contracts/v1/FiatTokenProxy.sol": {
+ "keccak256": "0x30fc5a64a101f783b2c745624d4c77b03a8f6373315857dc637581a189963f74",
+ "urls": [
+ "bzz-raw://f5de3f5569c8ac27ca793653613ca320c0ce77617510c31e7451d9b32f83ddb0",
+ "dweb:/ipfs/QmYQq9xh4jNwCH9KUDbWqttj5MWMfY2iAZRzrQf4cHh2nA"
+ ],
+ "license": "Apache-2.0"
+ },
+ "node_modules/@openzeppelin/contracts/utils/Address.sol": {
+ "keccak256": "0x28911e614500ae7c607a432a709d35da25f3bc5ddc8bd12b278b66358070c0ea",
+ "urls": [
+ "bzz-raw://256c8c8af5eb072bc473226ab2b2187149b8fc04f5f4a4820db22527f5ce8e3c",
+ "dweb:/ipfs/QmRvi5BhnL7Rxf85KrJhwM6RRhukm4tzoctRdgQEheNyiN"
+ ],
+ "license": "MIT"
+ }
+ },
+ "version": 1
+}
diff --git a/test/scripts/hardhat/testData/V2_2UpgraderDeploymentTrace.json b/test/scripts/hardhat/testData/V2_2UpgraderDeploymentTrace.json
new file mode 100644
index 000000000..d167ac5df
--- /dev/null
+++ b/test/scripts/hardhat/testData/V2_2UpgraderDeploymentTrace.json
@@ -0,0 +1,22 @@
+{
+ "from": "0x2ba937d2c71d0fbbeda8ce3bf02a8b88727961ec",
+ "gas": "0xe4e1c0",
+ "gasUsed": "0x7e83ee",
+ "to": "0x9999fa87f5a1d1c64e7c709838b92006ab0cc1ad",
+ "input": "0x60806040523480156200001157600080fd5b50604051620040d0380380620040d0833981810160405260a08110156200003757600080fd5b8151602083015160408085015160608601805192519496939591949391820192846401000000008211156200006b57600080fd5b9083019060208201858111156200008157600080fd5b82518660208202830111640100000000821117156200009f57600080fd5b82525081516020918201928201910280838360005b83811015620000ce578181015183820152602001620000b4565b5050505090500160405260200180516040519392919084640100000000821115620000f857600080fd5b9083019060208201858111156200010e57600080fd5b82516401000000008111828201881017156200012957600080fd5b82525081516020918201929091019080838360005b83811015620001585781810151838201526020016200013e565b50505050905090810190601f168015620001865780820380516001836020036101000a031916815260200191505b50604052505050848484620001a1336200027460201b60201c565b600180546001600160a01b039485166001600160a01b0319918216179091556002805493851693821693909317909255600380549190931691161790556040518590620001ee9062000296565b6001600160a01b03909116815260405190819003602001906000f0801580156200021c573d6000803e3d6000fd5b50600480546001600160a01b0319166001600160a01b0392909216919091179055815162000252906005906020850190620002a4565b508051620002689060069060208401906200030e565b505050505050620003c7565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b610ebf806200321183390190565b828054828255906000526020600020908101928215620002fc579160200282015b82811115620002fc57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620002c5565b506200030a9291506200038f565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200035157805160ff191683800117855562000381565b8280016001018555821562000381579182015b828111156200038157825182559160200191906001019062000364565b506200030a929150620003b0565b5b808211156200030a5780546001600160a01b031916815560010162000390565b5b808211156200030a5760008155600101620003b1565b612e3a80620003d76000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063d8f6a8f61161005b578063d8f6a8f614610176578063ec5568891461017e578063f2fde38b14610186576100be565b80638da5cb5b14610166578063d55ec6971461016e576100be565b80633f247fe7116100a75780633f247fe71461014c5780635c60da1b1461015657806363b0e66a1461015e576100be565b80632d4efffe146100c35780633200867b146100f4575b600080fd5b6100cb6101b9565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100fc6101d5565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610138578181015183820152602001610120565b505050509050019250505060405180910390f35b610154610244565b005b6100cb610484565b6100cb6104a0565b6100cb6104bc565b6101546104d8565b610154612682565b6100cb6127a1565b6101546004803603602081101561019c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166127bd565b60035473ffffffffffffffffffffffffffffffffffffffff1690565b6060600580548060200260200160405190810160405280929190818152602001828054801561023a57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161020f575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b15801561034057600080fd5b505afa158015610354573d6000803e3d6000fd5b505050506040513d602081101561036a57600080fd5b50519050801561048057604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015260248101839052905173ffffffffffffffffffffffffffffffffffffffff84169163a9059cbb9160448083019260209291908290030181600087803b1580156103e957600080fd5b505af11580156103fd573d6000803e3d6000fd5b505050506040513d602081101561041357600080fd5b505161048057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4661696c656420746f2077697468647261772046696174546f6b656e00000000604482015290519081900360640190fd5b5050565b60025473ffffffffffffffffffffffffffffffffffffffff1690565b60045473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60048054604080517f70a0823100000000000000000000000000000000000000000000000000000000815230938101939093525173ffffffffffffffffffffffffffffffffffffffff9091169160009183916370a08231916024808301926020929190829003018186803b1580156105d557600080fd5b505afa1580156105e9573d6000803e3d6000fd5b505050506040513d60208110156105ff57600080fd5b5051905062030d4081101561065f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612d936022913960400191505060405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156106c857600080fd5b505afa1580156106dc573d6000803e3d6000fd5b505050506040513d60208110156106f257600080fd5b505190506106fe612cc4565b6040518061018001604052808573ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561075057600080fd5b505afa158015610764573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156107ab57600080fd5b81019080805160405193929190846401000000008211156107cb57600080fd5b9083019060208201858111156107e057600080fd5b82516401000000008111828201881017156107fa57600080fd5b82525081516020918201929091019080838360005b8381101561082757818101518382015260200161080f565b50505050905090810190601f1680156108545780820380516001836020036101000a031916815260200191505b5060405250505081526020018573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156108a657600080fd5b505afa1580156108ba573d6000803e3d6000fd5b505050506040513d60208110156108d057600080fd5b505160ff168152604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160209092019173ffffffffffffffffffffffffffffffffffffffff88169163e5a6b10f916004808301926000929190829003018186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561099e57600080fd5b81019080805160405193929190846401000000008211156109be57600080fd5b9083019060208201858111156109d357600080fd5b82516401000000008111828201881017156109ed57600080fd5b82525081516020918201929091019080838360005b83811015610a1a578181015183820152602001610a02565b50505050905090810190601f168015610a475780820380516001836020036101000a031916815260200191505b5060405250505081526020018573ffffffffffffffffffffffffffffffffffffffff166354fd4d506040518163ffffffff1660e01b815260040160006040518083038186803b158015610a9957600080fd5b505afa158015610aad573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015610af457600080fd5b8101908080516040519392919084640100000000821115610b1457600080fd5b908301906020820185811115610b2957600080fd5b8251640100000000811182820188101715610b4357600080fd5b82525081516020918201929091019080838360005b83811015610b70578181015183820152602001610b58565b50505050905090810190601f168015610b9d5780820380516001836020036101000a031916815260200191505b5060405250505081526020018573ffffffffffffffffffffffffffffffffffffffff16633644e5156040518163ffffffff1660e01b815260040160206040518083038186803b158015610bef57600080fd5b505afa158015610c03573d6000803e3d6000fd5b505050506040513d6020811015610c1957600080fd5b50518152604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8916926335d99f359260048083019392829003018186803b158015610c8557600080fd5b505afa158015610c99573d6000803e3d6000fd5b505050506040513d6020811015610caf57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f6d3c5bbe000000000000000000000000000000000000000000000000000000008152905160209384019392891692636d3c5bbe9260048082019391829003018186803b158015610d1f57600080fd5b505afa158015610d33573d6000803e3d6000fd5b505050506040513d6020811015610d4957600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160209384019392891692639fd0506d9260048082019391829003018186803b158015610db957600080fd5b505afa158015610dcd573d6000803e3d6000fd5b505050506040513d6020811015610de357600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517fbd10243000000000000000000000000000000000000000000000000000000000815290516020938401939289169263bd1024309260048082019391829003018186803b158015610e5357600080fd5b505afa158015610e67573d6000803e3d6000fd5b505050506040513d6020811015610e7d57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f38a631830000000000000000000000000000000000000000000000000000000081529051602093840193928916926338a631839260048082019391829003018186803b158015610eed57600080fd5b505afa158015610f01573d6000803e3d6000fd5b505050506040513d6020811015610f1757600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160209384019392891692635c975abb9260048082019391829003018186803b158015610f8757600080fd5b505afa158015610f9b573d6000803e3d6000fd5b505050506040513d6020811015610fb157600080fd5b505115158152604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8916926318160ddd9260048083019392829003018186803b15801561101f57600080fd5b505afa158015611033573d6000803e3d6000fd5b505050506040513d602081101561104957600080fd5b50519052600154600254604080517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529051939450911691633659cfe69160248082019260009290919082900301818387803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b5050600154600354604080517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529051919092169350638f2839709250602480830192600092919082900301818387803b15801561115557600080fd5b505af1158015611169573d6000803e3d6000fd5b5050600154604080517f430239b400000000000000000000000000000000000000000000000000000000815260048101918252600580546044830181905273ffffffffffffffffffffffffffffffffffffffff909416955085945063430239b49390926006929091829160248101916064909101908690801561122257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116111f7575b50508381038252845460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001841615020190911604808252602090910190859080156112b45780601f10611289576101008083540402835291602001916112b4565b820191906000526020600020905b81548152906001019060200180831161129757829003601f168201915b5050945050505050600060405180830381600087803b1580156112d657600080fd5b505af11580156112ea573d6000803e3d6000fd5b505050506112f6612cc4565b6040518061018001604052808373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561134857600080fd5b505afa15801561135c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156113a357600080fd5b81019080805160405193929190846401000000008211156113c357600080fd5b9083019060208201858111156113d857600080fd5b82516401000000008111828201881017156113f257600080fd5b82525081516020918201929091019080838360005b8381101561141f578181015183820152602001611407565b50505050905090810190601f16801561144c5780820380516001836020036101000a031916815260200191505b5060405250505081526020018373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561149e57600080fd5b505afa1580156114b2573d6000803e3d6000fd5b505050506040513d60208110156114c857600080fd5b505160ff168152604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160209092019173ffffffffffffffffffffffffffffffffffffffff86169163e5a6b10f916004808301926000929190829003018186803b15801561153b57600080fd5b505afa15801561154f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561159657600080fd5b81019080805160405193929190846401000000008211156115b657600080fd5b9083019060208201858111156115cb57600080fd5b82516401000000008111828201881017156115e557600080fd5b82525081516020918201929091019080838360005b838110156116125781810151838201526020016115fa565b50505050905090810190601f16801561163f5780820380516001836020036101000a031916815260200191505b5060405250505081526020018373ffffffffffffffffffffffffffffffffffffffff166354fd4d506040518163ffffffff1660e01b815260040160006040518083038186803b15801561169157600080fd5b505afa1580156116a5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156116ec57600080fd5b810190808051604051939291908464010000000082111561170c57600080fd5b90830190602082018581111561172157600080fd5b825164010000000081118282018810171561173b57600080fd5b82525081516020918201929091019080838360005b83811015611768578181015183820152602001611750565b50505050905090810190601f1680156117955780820380516001836020036101000a031916815260200191505b5060405250505081526020018373ffffffffffffffffffffffffffffffffffffffff16633644e5156040518163ffffffff1660e01b815260040160206040518083038186803b1580156117e757600080fd5b505afa1580156117fb573d6000803e3d6000fd5b505050506040513d602081101561181157600080fd5b50518152604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8716926335d99f359260048083019392829003018186803b15801561187d57600080fd5b505afa158015611891573d6000803e3d6000fd5b505050506040513d60208110156118a757600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905160209384019392871692638da5cb5b9260048082019391829003018186803b15801561191757600080fd5b505afa15801561192b573d6000803e3d6000fd5b505050506040513d602081101561194157600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160209384019392871692639fd0506d9260048082019391829003018186803b1580156119b157600080fd5b505afa1580156119c5573d6000803e3d6000fd5b505050506040513d60208110156119db57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517fbd10243000000000000000000000000000000000000000000000000000000000815290516020938401939287169263bd1024309260048082019391829003018186803b158015611a4b57600080fd5b505afa158015611a5f573d6000803e3d6000fd5b505050506040513d6020811015611a7557600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f38a631830000000000000000000000000000000000000000000000000000000081529051602093840193928716926338a631839260048082019391829003018186803b158015611ae557600080fd5b505afa158015611af9573d6000803e3d6000fd5b505050506040513d6020811015611b0f57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160209384019392871692635c975abb9260048082019391829003018186803b158015611b7f57600080fd5b505afa158015611b93573d6000803e3d6000fd5b505050506040513d6020811015611ba957600080fd5b505115158152604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8716926318160ddd9260048083019392829003018186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d6020811015611c4157600080fd5b505190529050611c518382612910565b611ca6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612db56022913960400191505060405180910390fd5b60066040518082805460018160011615610100020316600290048015611d035780601f10611ce1576101008083540402835291820191611d03565b820191906000526020600020905b815481529060010190602001808311611cef575b505091505060405180910390208273ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611d5657600080fd5b505afa158015611d6a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015611db157600080fd5b8101908080516040519392919084640100000000821115611dd157600080fd5b908301906020820185811115611de657600080fd5b8251640100000000811182820188101715611e0057600080fd5b82525081516020918201929091019080838360005b83811015611e2d578181015183820152602001611e15565b50505050905090810190601f168015611e5a5780820380516001836020036101000a031916815260200191505b506040525050508051906020012014611ed457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f56325f3255706772616465723a2073796d626f6c206e6f742075706461746564604482015290519081900360640190fd5b848273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611f3c57600080fd5b505afa158015611f50573d6000803e3d6000fd5b505050506040513d6020811015611f6657600080fd5b505114611fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612d4a6023913960400191505060405180910390fd5b604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152620186a06024820152905173ffffffffffffffffffffffffffffffffffffffff84169163a9059cbb9160448083019260209291908290030181600087803b15801561203557600080fd5b505af1158015612049573d6000803e3d6000fd5b505050506040513d602081101561205f57600080fd5b5051801561210f575061207584620186a0612b0d565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b1580156120e157600080fd5b505afa1580156120f5573d6000803e3d6000fd5b505050506040513d602081101561210b57600080fd5b5051145b80156121bd575061212385620186a0612b81565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561218f57600080fd5b505afa1580156121a3573d6000803e3d6000fd5b505050506040513d60208110156121b957600080fd5b5051145b612212576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612d286022913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663095ea7b387620186a06040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561228657600080fd5b505af115801561229a573d6000803e3d6000fd5b505050506040513d60208110156122b057600080fd5b505180156123615750604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff888116602483015291519184169163dd62ed3e91604480820192602092909190829003018186803b15801561232f57600080fd5b505afa158015612343573d6000803e3d6000fd5b505050506040513d602081101561235957600080fd5b5051620186a0145b80156124125750604080517f23b872dd000000000000000000000000000000000000000000000000000000008152306004820152336024820152620186a06044820152905173ffffffffffffffffffffffffffffffffffffffff8816916323b872dd9160648083019260209291908290030181600087803b1580156123e557600080fd5b505af11580156123f9573d6000803e3d6000fd5b505050506040513d602081101561240f57600080fd5b50515b80156124b95750604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152306004820152336024820152905173ffffffffffffffffffffffffffffffffffffffff84169163dd62ed3e916044808301926020929190829003018186803b15801561248b57600080fd5b505afa15801561249f573d6000803e3d6000fd5b505050506040513d60208110156124b557600080fd5b5051155b801561256757506124cd8462030d40612b0d565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561253957600080fd5b505afa15801561254d573d6000803e3d6000fd5b505050506040513d602081101561256357600080fd5b5051145b8015612615575061257b8562030d40612b81565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b1580156125e757600080fd5b505afa1580156125fb573d6000803e3d6000fd5b505050506040513d602081101561261157600080fd5b5051145b61266a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612dd7602e913960400191505060405180910390fd5b612672610244565b61267a612bf8565b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461270857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600154600354604080517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015290519190921691638f28397091602480830192600092919082900301818387803b15801561277f57600080fd5b505af1158015612793573d6000803e3d6000fd5b5050505061279f612bf8565b565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff16331461284357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166128af576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612d6d6026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a161290d81612c7d565b50565b60008160000151805190602001208360000151805190602001201480156129445750816020015160ff16836020015160ff16145b80156129655750816040015180519060200120836040015180519060200120145b80156129865750816060015180519060200120836060015180519060200120145b8015612999575081608001518360800151145b80156129d857508160a0015173ffffffffffffffffffffffffffffffffffffffff168360a0015173ffffffffffffffffffffffffffffffffffffffff16145b8015612a1757508160c0015173ffffffffffffffffffffffffffffffffffffffff168360c0015173ffffffffffffffffffffffffffffffffffffffff16145b8015612a5657508160e0015173ffffffffffffffffffffffffffffffffffffffff168360e0015173ffffffffffffffffffffffffffffffffffffffff16145b8015612a97575081610100015173ffffffffffffffffffffffffffffffffffffffff1683610100015173ffffffffffffffffffffffffffffffffffffffff16145b8015612ad8575081610120015173ffffffffffffffffffffffffffffffffffffffff1683610120015173ffffffffffffffffffffffffffffffffffffffff16145b8015612af1575081610140015115158361014001511515145b8015612b065750816101600151836101600151145b9392505050565b600082820183811015612b0657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082821115612bf257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60048054604080517fec1e6a4f000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263ec1e6a4f92828201926000929082900301818387803b158015612c6157600080fd5b505af1158015612c75573d6000803e3d6000fd5b503392505050ff5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60408051610180810182526060808252600060208301819052928201819052808201526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101919091529056fe56325f3255706772616465723a207472616e736665722074657374206661696c656456325f3255706772616465723a2062616c616e63654f662074657374206661696c65644f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737356325f3255706772616465723a20302e322046696174546f6b656e206e656564656456325f3255706772616465723a206d657461646174612074657374206661696c656456325f3255706772616465723a20617070726f76652f7472616e7366657246726f6d2074657374206661696c6564a26469706673582212204819915d274abf3d15a3786f32e333cd2999420e94d010d1542e76b4cfa573f564736f6c634300060c0033608060405234801561001057600080fd5b50604051610ebf380380610ebf8339818101604052602081101561003357600080fd5b5051808061004033610068565b600180546001600160a01b0319166001600160a01b03929092169190911790555061008a9050565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b610e26806100996000396000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80636d3c5bbe116100cd578063bd10243011610081578063ec1e6a4f11610066578063ec1e6a4f14610316578063ec55688914610320578063f2fde38b1461032857610151565b8063bd10243014610306578063e5a6b10f1461030e57610151565b80638da5cb5b116100b25780638da5cb5b146102ee57806395d89b41146102f65780639fd0506d146102fe57610151565b80636d3c5bbe146102b357806370a08231146102bb57610151565b806335d99f351161012457806338a631831161010957806338a631831461029b57806354fd4d50146102a35780635c975abb146102ab57610151565b806335d99f35146102625780633644e5151461029357610151565b806306fdde031461015657806318160ddd146101d357806323b872dd146101ed578063313ce56714610244575b600080fd5b61015e61035b565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610198578181015183820152602001610180565b50505050905090810190601f1680156101c55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101db6104d6565b60408051918252519081900360200190f35b6102306004803603606081101561020357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610572565b604080519115158252519081900360200190f35b61024c61062d565b6040805160ff9092168252519081900360200190f35b61026a610698565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6101db610703565b61026a61076e565b61015e6107d9565b610230610844565b61026a6108af565b6101db600480360360208110156102d157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661091a565b61026a6109c3565b61015e6109df565b61026a610a4a565b61026a610ab5565b61015e610b20565b61031e610b8b565b005b61026a610c14565b61031e6004803603602081101561033e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c30565b600154604080517f06fdde03000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916306fdde03916004808301926000929190829003018186803b1580156103c657600080fd5b505afa1580156103da573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561042157600080fd5b810190808051604051939291908464010000000082111561044157600080fd5b90830190602082018581111561045657600080fd5b825164010000000081118282018810171561047057600080fd5b82525081516020918201929091019080838360005b8381101561049d578181015183820152602001610485565b50505050905090810190601f1680156104ca5780820380516001836020036101000a031916815260200191505b50604052505050905090565b600154604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916318160ddd916004808301926020929190829003018186803b15801561054157600080fd5b505afa158015610555573d6000803e3d6000fd5b505050506040513d602081101561056b57600080fd5b5051905090565b600154604080517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015260448201859052915160009392909216916323b872dd9160648082019260209290919082900301818787803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050506040513d602081101561062357600080fd5b5051949350505050565b600154604080517f313ce567000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163313ce567916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916335d99f35916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f3644e515000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691633644e515916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f38a63183000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916338a63183916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f54fd4d50000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916354fd4d50916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691638da5cb5b916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152915160009392909216916370a0823191602480820192602092909190829003018186803b15801561099157600080fd5b505afa1580156109a5573d6000803e3d6000fd5b505050506040513d60208110156109bb57600080fd5b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600154604080517f95d89b41000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916395d89b41916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691639fd0506d916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fbd102430000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163bd102430916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff169163e5a6b10f916004808301926000929190829003018186803b1580156103c657600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610c1157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b33ff5b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cb657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610dcb6026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a1610d8081610d83565b50565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220383c813e998c1388f31580a958b4ef51a545c3007a0be737f82b32515a060b0d64736f6c634300060c0033000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000043506849d7c04f9138d1a2050bbf3a0c054402dd000000000000000000000000807a96288a1a408dbc13de2b1d087d10356395d200000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001a8000000000000000000000000000000000000000000000000000000000000000ce000000000000000000000000aa05f7c7eb9af63d6cc03c36c4f4ef6c37431ee00000000000000000000000007f367cc41522ce07553e823bf3be79a889debe1b0000000000000000000000001da5821544e25c636c1417ba96ade4cf6d2f9b5a0000000000000000000000007db418b5d567a4e0e8c59ad71be1fce48f3e610700000000000000000000000072a5843cc08275c8171e582972aa4fda8c397b2a0000000000000000000000007f19720a857f834887fc9a7bc0a0fbe7fc7f8102000000000000000000000000d882cfc20f52f2599d84b8e8d58c7fb62cfe344b0000000000000000000000009f4cda013e354b8fc285bf4b9a60460cee7f7ea9000000000000000000000000308ed4b7b49797e1a98d3818bff6fe5385410370000000000000000000000000e7aa314c77f4233c18c6cc84384a9247c0cf367b00000000000000000000000019aa5fe80d33a56d56c78e82ea5e50e5d80b4dff0000000000000000000000002f389ce8bd8ff92de3402ffce4691d17fc4f6535000000000000000000000000a7e5d5a720f06526557c513402f2e6b5fa20b0080000000000000000000000003cbded43efdaf0fc77b9c55f6fc9988fcc9b757d00000000000000000000000067d40ee1a85bf4a4bb7ffae16de985e8427b6b450000000000000000000000006f1ca141a28907f78ebaa64fb83a9088b02a83520000000000000000000000006acdfba02d390b97ac2b2d42a63e85293bcc160e00000000000000000000000048549a34ae37b12f6a30566245176994e17c6b4a0000000000000000000000005512d943ed1f7c8a43f3435c85f7ab68b30121b0000000000000000000000000c455f7fd3e0e12afd51fba5c106909934d8a0e4a000000000000000000000000fae5a6d3bd9bd24a3ed2f2a8a6031c83976c19a20000000000000000000000005eb95f30bd4409cfaadeba75cd8d9c2ce4ed992a000000000000000000000000461270bd08dfa98edec980345fd56d578a2d8f49000000000000000000000000fec8a60023265364d066a1212fde3930f6ae8da70000000000000000000000008576acc5c05d6ce88f4e49bf65bdf0c62f91353c000000000000000000000000901bb9583b24d97e995513c6778dc6888ab6870e0000000000000000000000007ff9cfad3877f21d41da833e2f775db0569ee3d9000000000000000000000000098b716b8aaf21512996dc57eb0615e2383e2f96000000000000000000000000a0e1c89ef1a489c9c7de96311ed5ce5d32c20e4b0000000000000000000000003cffd56b47b7b41c56258d9c7731abadc360e07300000000000000000000000053b6936513e738f44fb50d2b9476730c0ab3bfc1000000000000000000000000cce63fd31e9053c110c74cebc37c8e358a6aa5bd00000000000000000000000035fb6f6db4fb05e6a4ce86f2c93691425626d4b1000000000000000000000000f7b31119c2682c88d88d455dbb9d5932c65cf1be0000000000000000000000003e37627deaa754090fbfbb8bd226c1ce66d255e900000000000000000000000008723392ed15743cc38513c4925f5e6be5c1724300000000000000000000000006caa9a5fd7e3dc3b3157973455cbe9b9c2b14d20000000000000000000000002d66370666d7b9315e6e7fdb47f41ad7222798330000000000000000000000009ff43bd969e8dbc383d1aca50584c14266f3d876000000000000000000000000bfd88175e4ae6f7f2ee4b01bf96cf48d2bcb41960000000000000000000000008589427373d6d84e98730d7795d8f6f8731fda16000000000000000000000000722122df12d4e14e13ac3b6895a86e84145b6967000000000000000000000000dd4c48c0b24039969fc16d1cdf626eab821d3384000000000000000000000000d90e2f925da726b50c4ed8d0fb90ad053324f31b000000000000000000000000d96f2b1c14db8458374d9aca76e26c3d183643070000000000000000000000004736dcf1b7a3d580672cce6e7c65cd5cc9cfba9d000000000000000000000000d4b88df4d29f5cedd6857912842cff3b20c8cfa3000000000000000000000000910cbd523d972eb0a6f4cae4618ad62622b39dbf000000000000000000000000a160cdab225685da1d56aa342ad8841c3b53f291000000000000000000000000fd8610d20aa15b7b2e3be39b396a1bc3516c7144000000000000000000000000f60dd140cff0706bae9cd734ac3ae76ad9ebc32a00000000000000000000000022aaa7720ddd5388a3c0a3333430953c68f1849b000000000000000000000000ba214c1c1928a32bffe790263e38b4af9bfcd659000000000000000000000000b1c8094b234dce6e03f10a5b673c1d8c69739a00000000000000000000000000527653ea119f3e6a1f5bd18fbf4714081d7b31ce00000000000000000000000058e8dcc13be9780fc42e8723d8ead4cf46943df2000000000000000000000000d691f27f38b395864ea86cfc7253969b409c362d000000000000000000000000aeaac358560e11f52454d997aaff2c5731b6f8a60000000000000000000000001356c899d8c9467c7f71c195612f8a395abf2f0a000000000000000000000000a60c772958a3ed56c1f15dd055ba37ac8e523a0d000000000000000000000000169ad27a470d064dede56a2d3ff727986b15d52b0000000000000000000000000836222f2b2b24a3f36f98668ed8f0b38d1a872f000000000000000000000000f67721a2d8f736e75a49fdd7fad2e31d8676542a0000000000000000000000009ad122c22b14202b4490edaf288fdb3c7cb3ff5e00000000000000000000000007687e702b410fa43f4cb4af7fa097918ffd273000000000000000000000000094a1b5cdb22c43faab4abeb5c74999895464ddaf000000000000000000000000b541fc07bc7619fd4062a54d96268525cbc6ffef00000000000000000000000012d66f87a04a9e220743712ce6d9bb1b5616b8fc00000000000000000000000047ce0c6ed5b0ce3d3a51fdb1c52dc66a7c3c293600000000000000000000000023773e65ed146a459791799d01336db287f25334000000000000000000000000d21be7248e0197ee08e0c20d4a96debdac3d20af000000000000000000000000610b717796ad172b316836ac95a2ffad065ceab4000000000000000000000000178169b423a011fff22b9e3f3abea13414ddd0f1000000000000000000000000bb93e510bbcd0b7beb5a853875f9ec60275cf4980000000000000000000000002717c5e28cf931547b621a5dddb772ab6a35b70100000000000000000000000003893a7c7463ae47d46bc7f091665f1893656003000000000000000000000000ca0840578f57fe71599d29375e16783424023357000000000000000000000000d93a9c5c4d399dc5f67b67cdb30d16a7bb5749150000000000000000000000003ad9db589d201a710ed237c829c7860ba86510fc000000000000000000000000c2a3829f459b3edd87791c74cd45402ba0a20be3000000000000000000000000e7800b61479695ec74e4b219f409f67bd1055a27000000000000000000000000815f335f976301f496167bfef237f0622f92ac3800000000000000000000000081c4d8816b29147c542dde87485608204690acf2000000000000000000000000489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec000000000000000000000000330bdfade01ee9bf63c209ee33102dd334618e0a000000000000000000000000d47438c816c9e7f2e2888e060936a499af9582b300000000000000000000000084443cfd09a48af6ef360c6976c5392ac5023a1f000000000000000000000000d82ed8786d7c69dc7e052f7a542ab047971e73d2000000000000000000000000756c4628e57f7e7f8a459ec2752968360cf4d1aa0000000000000000000000005cab7692d4e94096462119ab7bf57319726eed2a00000000000000000000000009193888b3f38c82dedfda55259a82c0e7de875e00000000000000000000000088fd245fedec4a936e700f9173454d1931b4c307000000000000000000000000653477c392c16b0765603074f157314cc4f40c320000000000000000000000002573bac39ebe2901b4389cd468f2872cf7767faf000000000000000000000000b20c66c4de72433f3ce747b58b86830c459ca91100000000000000000000000026903a5a198d571422b2b4ea08b56a37cbd68c890000000000000000000000002fc93484614a34f26f7970cbb94615ba109bb4bf00000000000000000000000001e2919679362dfbc9ee1644ba9c6da6d6245bb1000000000000000000000000f4b067dd14e95bab89be928c07cb22e3c94e0daa0000000000000000000000005f6c97c6ad7bdd0ae7e0dd4ca33a4ed3fdabd4d7000000000000000000000000746aebc06d2ae31b71ac51429a19d54e797878e90000000000000000000000003efa30704d2b8bbac821307230376556cf8cc39e00000000000000000000000077777feddddffc19ff86db637967013e6c6a116c000000000000000000000000b04e030140b30c27bcdfaafffa98c57d80eda7b4000000000000000000000000ffbac21a641dcfe4552920138d90f3638b3c9fba000000000000000000000000cee71753c9820f063b38fdbe4cfdaf1d3d928a800000000000000000000000002f50508a8a3d323b91336fa3ea6ae50e55f321850000000000000000000000005efda50f22d34f262c29268506c5fa42cb56a1ce00000000000000000000000094c92f096437ab9958fc0a37f09348f30389ae79000000000000000000000000743494b60097a2230018079c02fe21a7b687eaa5000000000000000000000000179f48c78f57a3a78f0608cc9197b8972921d1d2000000000000000000000000df3a408c53e5078af6e8fb2a85088d46ee09a61b000000000000000000000000d692fd2d0b2fbd2e52cfa5b5b9424bc981c30696000000000000000000000000edc5d01286f99a066559f60a585406f3878a033e000000000000000000000000776198ccf446dfa168347089d7338879273172cf000000000000000000000000242654336ca2205714071898f67e254eb49acdce00000000000000000000000094be88213a387e992dd87de56950a9aef34b9448000000000000000000000000538ab61e8a9fc1b2f93b3dd9011d662d89be6fe600000000000000000000000023173fe8b96a4ad8d2e17fb83ea5dcccdca1ae5200000000000000000000000005e0b5b40b7b66098c2161a5ee11c5740a3a7c4500000000000000000000000057b2b8c82f065de8ef5573f9730fc1449b403c9f0000000000000000000000008281aa6795ade17c8973e1aedca380258bc124f9000000000000000000000000d8d7de3349ccaa0fde6298fe6d7b7d0d34586193000000000000000000000000833481186f16cece3f1eeea1a694c42034c3a0db000000000000000000000000407cceeaa7c95d2fe2250bf9f2c105aa7aafb512000000000000000000000000d5d6f8d9e784d0e26222ad3834500801a68d027d000000000000000000000000cc84179ffd19a1627e79f8648d09e095252bc41800000000000000000000000076d85b4c0fc497eecc38902397ac608000a066070000000000000000000000000e3a09dda6b20afbb34ac7cd4a6881493f3e7bf7000000000000000000000000723b78e67497e85279cb204544566f4dc5d2aca00000000000000000000000003aac1cc67c2ec5db4ea850957b967ba153ad62790000000000000000000000006bf694a291df3fec1f7e69701e3ab6c592435ae7000000000000000000000000af8d1839c3c67cf571aa74b5c12398d4901147b3000000000000000000000000a5c2254e4253490c54cef0a4347fddb8f75a4998000000000000000000000000af4c0b70b2ea9fb7487c7cbb37ada259579fe040000000000000000000000000df231d99ff8b6c6cbf4e9b9a945cbacef93391780000000000000000000000001e34a77868e19a6647b1f2f47b51ed72dede95dd000000000000000000000000502371699497d08d5339c870851898d6d72521dd0000000000000000000000005a14e72060c11313e38738009254a90968f58f51000000000000000000000000efe301d259f525ca1ba74a7977b80d5b060b3cca000000000000000000000000d0975b32cea532eadddfc9c60481976e39db34720000000000000000000000001967d8af5bd86a497fb3dd7899a020e47560daaf00000000000000000000000004dba1194ee10112fe6c3207c0687def0e78bacf00000000000000000000000008b2efdcdb8822efe5ad0eae55517cf5dc54425100000000000000000000000083e5bc4ffa856bb84bb88581f5dd62a433a25e0d0000000000000000000000000ee5067b06776a89ccc7dc8ee369984ad7db5e0600000000000000000000000044b3d59fe4da798a43de3689be0a2ab508bc0067000000000000000000000000bf4f36efa3ac655a1d86f6c32b648a90271443f400000000000000000000000039d908dac893cbcb53cc86e0ecc369aa4def1a290000000000000000000000007f2863dc306fe5be920d311f5eeef842bae16ce8000000000000000000000000f8a9ab377ce63592583767b34602e130e38ebdca0000000000000000000000006572760df65696a671eb17575b995daca056237d00000000000000000000000042b756987dee8a21508c4e470bfefb5e36a5e4e40000000000000000000000009253f800c8a03b9184ceb9280361e5055893192c0000000000000000000000004f47bc496083c727c5fbe3ce9cdf2b0f6496270c0000000000000000000000008a8a2436fc920e6c73c3a9e9a00b8d937812ee0d000000000000000000000000088aaa322d955816d8a00b3ad58139543556cb61000000000000000000000000c34586a57d59fbd08865298203cf28cd10ad970800000000000000000000000038735f03b30fbc022ddd06abed01f0ca823c6a940000000000000000000000008bebb5bc4f8ee9d2978e70c5dc178543fb9dc0d9000000000000000000000000eb53f63ff2c8f576de0752d0fb603ddc79318b26000000000000000000000000fc672c73ca5c7234edc82552e4a0c8fc247d32ac00000000000000000000000008c3fd4ae6a596083a528614d71e17c2ff2f4b8e0000000000000000000000000c51498f3ae1a0cfe696820a1b4e9af85b918bc600000000000000000000000097b1043abd9e6fc31681635166d430a458d14f9c000000000000000000000000b6f5ec1a0a9cd1526536d3f0426c429529471f4000000000000000000000000048bead89e696ee93b04913cb0006f35adb844537000000000000000000000000efeef8e968a0db92781ac7b3b7c821909ef10c88000000000000000000000000027f1571aca57354223276722dc7b572a5b05cd8000000000000000000000000d71c94052989e209ba713deb66e0a8f72b913b70000000000000000000000000dcbeffbecce100cce9e4b153c4e15cb8856431930000000000000000000000005f48c2a71b2cc96e3f0ccae4e39318ff0dc375b20000000000000000000000005a7a51bfb49f190e5a6060a5bc6052ac14a3b59f000000000000000000000000ed6e0a7e4ac94d976eebfb82ccf777a3c6bad921000000000000000000000000797d7ae72ebddcdea2a346c1834e04d1f8df102b000000000000000000000000931546d9e66836abf687d2bc64b30407bac8c56800000000000000000000000043fa21d92141ba9db43052492e0deee5aa5f0a930000000000000000000000006be0ae71e6c41f2f9d0d1a3b8d0f75e6f6a0b46e0000000000000000000000003d7cfda9254a05d3eeae06ab2a7c46b8e950d7440000000000000000000000009c220048401fa6819e59a15e67d96ceffb9043ac00000000000000000000000026e0d078aac76c9ba2b348825b413744a82a2cfd0000000000000000000000009c2bc757b66f24d60f016b6237f8cdd414a879fa000000000000000000000000530a64c0ce595026a4a556b703644228179e2d570000000000000000000000002e13ea767da12f504ceaaaebe5950488498dc2d20000000000000000000000007de5ab1914e241177344936dc33b4a8157c98248000000000000000000000000fac583c0cf07ea434052c49115a4682172ab6b4f000000000000000000000000be5e683633ddd17d8a89b4e10860a0e426c5ed24000000000000000000000000961c5be54a2ffc17cf4cb021d863c42dacd47fc1000000000000000000000000a6cc8ab881debc3c9e8adb32549d0cbe614168c5000000000000000000000000983a81ca6fb1e441266d2fbcb7d8e530ac2e05a20000000000000000000000005b93aadbd3e507bf2e3a68e8cd760c82fba541f10000000000000000000000003ac79da68cc906240f4c62d7b2bfe64fb992e22c0000000000000000000000005095cbfc0ff59e63745ea01f5a722f9d7564b4f60000000000000000000000003ceab17d3fb1ee10e8424ca2b649c54a0643ed880000000000000000000000001ea6c03601ba054441709a4a345addc05937fd9c000000000000000000000000d492e57806c0abd3f0932205c5bb3086aae4977800000000000000000000000068b66ce34da6bf45110e0064f232acbd8e7a55310000000000000000000000007d7c4dddf9188d0c170d438d08eb94370c5886300000000000000000000000009078b13962fbc7d93f624ab9395d60ff332a9af9000000000000000000000000d6d47fcea370d6fbd78de05e458bcc5d2d38c39000000000000000000000000025b903719548e94cb58907a0db4461ffd61deeb60000000000000000000000005ea884caf25a9d2b9fb1033cdd5300bd40c5d223000000000000000000000000ce5d11cc48eb1671a6e36829575578d2d4cca48f000000000000000000000000e997bfc0f7a6fd834176b0c92eb845b6696b8d09000000000000000000000000f44edc33a3c96e7e74ce9284a04db0d8af7eca4c00000000000000000000000034aa48e296273872649ef8d3782813fe9a77dc7200000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000",
+ "output": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063d8f6a8f61161005b578063d8f6a8f614610176578063ec5568891461017e578063f2fde38b14610186576100be565b80638da5cb5b14610166578063d55ec6971461016e576100be565b80633f247fe7116100a75780633f247fe71461014c5780635c60da1b1461015657806363b0e66a1461015e576100be565b80632d4efffe146100c35780633200867b146100f4575b600080fd5b6100cb6101b9565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100fc6101d5565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610138578181015183820152602001610120565b505050509050019250505060405180910390f35b610154610244565b005b6100cb610484565b6100cb6104a0565b6100cb6104bc565b6101546104d8565b610154612682565b6100cb6127a1565b6101546004803603602081101561019c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166127bd565b60035473ffffffffffffffffffffffffffffffffffffffff1690565b6060600580548060200260200160405190810160405280929190818152602001828054801561023a57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161020f575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9092169160009183916370a0823191602480820192602092909190829003018186803b15801561034057600080fd5b505afa158015610354573d6000803e3d6000fd5b505050506040513d602081101561036a57600080fd5b50519050801561048057604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015260248101839052905173ffffffffffffffffffffffffffffffffffffffff84169163a9059cbb9160448083019260209291908290030181600087803b1580156103e957600080fd5b505af11580156103fd573d6000803e3d6000fd5b505050506040513d602081101561041357600080fd5b505161048057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4661696c656420746f2077697468647261772046696174546f6b656e00000000604482015290519081900360640190fd5b5050565b60025473ffffffffffffffffffffffffffffffffffffffff1690565b60045473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60048054604080517f70a0823100000000000000000000000000000000000000000000000000000000815230938101939093525173ffffffffffffffffffffffffffffffffffffffff9091169160009183916370a08231916024808301926020929190829003018186803b1580156105d557600080fd5b505afa1580156105e9573d6000803e3d6000fd5b505050506040513d60208110156105ff57600080fd5b5051905062030d4081101561065f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612d936022913960400191505060405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156106c857600080fd5b505afa1580156106dc573d6000803e3d6000fd5b505050506040513d60208110156106f257600080fd5b505190506106fe612cc4565b6040518061018001604052808573ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561075057600080fd5b505afa158015610764573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156107ab57600080fd5b81019080805160405193929190846401000000008211156107cb57600080fd5b9083019060208201858111156107e057600080fd5b82516401000000008111828201881017156107fa57600080fd5b82525081516020918201929091019080838360005b8381101561082757818101518382015260200161080f565b50505050905090810190601f1680156108545780820380516001836020036101000a031916815260200191505b5060405250505081526020018573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156108a657600080fd5b505afa1580156108ba573d6000803e3d6000fd5b505050506040513d60208110156108d057600080fd5b505160ff168152604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160209092019173ffffffffffffffffffffffffffffffffffffffff88169163e5a6b10f916004808301926000929190829003018186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561099e57600080fd5b81019080805160405193929190846401000000008211156109be57600080fd5b9083019060208201858111156109d357600080fd5b82516401000000008111828201881017156109ed57600080fd5b82525081516020918201929091019080838360005b83811015610a1a578181015183820152602001610a02565b50505050905090810190601f168015610a475780820380516001836020036101000a031916815260200191505b5060405250505081526020018573ffffffffffffffffffffffffffffffffffffffff166354fd4d506040518163ffffffff1660e01b815260040160006040518083038186803b158015610a9957600080fd5b505afa158015610aad573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015610af457600080fd5b8101908080516040519392919084640100000000821115610b1457600080fd5b908301906020820185811115610b2957600080fd5b8251640100000000811182820188101715610b4357600080fd5b82525081516020918201929091019080838360005b83811015610b70578181015183820152602001610b58565b50505050905090810190601f168015610b9d5780820380516001836020036101000a031916815260200191505b5060405250505081526020018573ffffffffffffffffffffffffffffffffffffffff16633644e5156040518163ffffffff1660e01b815260040160206040518083038186803b158015610bef57600080fd5b505afa158015610c03573d6000803e3d6000fd5b505050506040513d6020811015610c1957600080fd5b50518152604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8916926335d99f359260048083019392829003018186803b158015610c8557600080fd5b505afa158015610c99573d6000803e3d6000fd5b505050506040513d6020811015610caf57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f6d3c5bbe000000000000000000000000000000000000000000000000000000008152905160209384019392891692636d3c5bbe9260048082019391829003018186803b158015610d1f57600080fd5b505afa158015610d33573d6000803e3d6000fd5b505050506040513d6020811015610d4957600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160209384019392891692639fd0506d9260048082019391829003018186803b158015610db957600080fd5b505afa158015610dcd573d6000803e3d6000fd5b505050506040513d6020811015610de357600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517fbd10243000000000000000000000000000000000000000000000000000000000815290516020938401939289169263bd1024309260048082019391829003018186803b158015610e5357600080fd5b505afa158015610e67573d6000803e3d6000fd5b505050506040513d6020811015610e7d57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f38a631830000000000000000000000000000000000000000000000000000000081529051602093840193928916926338a631839260048082019391829003018186803b158015610eed57600080fd5b505afa158015610f01573d6000803e3d6000fd5b505050506040513d6020811015610f1757600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160209384019392891692635c975abb9260048082019391829003018186803b158015610f8757600080fd5b505afa158015610f9b573d6000803e3d6000fd5b505050506040513d6020811015610fb157600080fd5b505115158152604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8916926318160ddd9260048083019392829003018186803b15801561101f57600080fd5b505afa158015611033573d6000803e3d6000fd5b505050506040513d602081101561104957600080fd5b50519052600154600254604080517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529051939450911691633659cfe69160248082019260009290919082900301818387803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b5050600154600354604080517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529051919092169350638f2839709250602480830192600092919082900301818387803b15801561115557600080fd5b505af1158015611169573d6000803e3d6000fd5b5050600154604080517f430239b400000000000000000000000000000000000000000000000000000000815260048101918252600580546044830181905273ffffffffffffffffffffffffffffffffffffffff909416955085945063430239b49390926006929091829160248101916064909101908690801561122257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116111f7575b50508381038252845460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001841615020190911604808252602090910190859080156112b45780601f10611289576101008083540402835291602001916112b4565b820191906000526020600020905b81548152906001019060200180831161129757829003601f168201915b5050945050505050600060405180830381600087803b1580156112d657600080fd5b505af11580156112ea573d6000803e3d6000fd5b505050506112f6612cc4565b6040518061018001604052808373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561134857600080fd5b505afa15801561135c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156113a357600080fd5b81019080805160405193929190846401000000008211156113c357600080fd5b9083019060208201858111156113d857600080fd5b82516401000000008111828201881017156113f257600080fd5b82525081516020918201929091019080838360005b8381101561141f578181015183820152602001611407565b50505050905090810190601f16801561144c5780820380516001836020036101000a031916815260200191505b5060405250505081526020018373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561149e57600080fd5b505afa1580156114b2573d6000803e3d6000fd5b505050506040513d60208110156114c857600080fd5b505160ff168152604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160209092019173ffffffffffffffffffffffffffffffffffffffff86169163e5a6b10f916004808301926000929190829003018186803b15801561153b57600080fd5b505afa15801561154f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561159657600080fd5b81019080805160405193929190846401000000008211156115b657600080fd5b9083019060208201858111156115cb57600080fd5b82516401000000008111828201881017156115e557600080fd5b82525081516020918201929091019080838360005b838110156116125781810151838201526020016115fa565b50505050905090810190601f16801561163f5780820380516001836020036101000a031916815260200191505b5060405250505081526020018373ffffffffffffffffffffffffffffffffffffffff166354fd4d506040518163ffffffff1660e01b815260040160006040518083038186803b15801561169157600080fd5b505afa1580156116a5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156116ec57600080fd5b810190808051604051939291908464010000000082111561170c57600080fd5b90830190602082018581111561172157600080fd5b825164010000000081118282018810171561173b57600080fd5b82525081516020918201929091019080838360005b83811015611768578181015183820152602001611750565b50505050905090810190601f1680156117955780820380516001836020036101000a031916815260200191505b5060405250505081526020018373ffffffffffffffffffffffffffffffffffffffff16633644e5156040518163ffffffff1660e01b815260040160206040518083038186803b1580156117e757600080fd5b505afa1580156117fb573d6000803e3d6000fd5b505050506040513d602081101561181157600080fd5b50518152604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8716926335d99f359260048083019392829003018186803b15801561187d57600080fd5b505afa158015611891573d6000803e3d6000fd5b505050506040513d60208110156118a757600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905160209384019392871692638da5cb5b9260048082019391829003018186803b15801561191757600080fd5b505afa15801561192b573d6000803e3d6000fd5b505050506040513d602081101561194157600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160209384019392871692639fd0506d9260048082019391829003018186803b1580156119b157600080fd5b505afa1580156119c5573d6000803e3d6000fd5b505050506040513d60208110156119db57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517fbd10243000000000000000000000000000000000000000000000000000000000815290516020938401939287169263bd1024309260048082019391829003018186803b158015611a4b57600080fd5b505afa158015611a5f573d6000803e3d6000fd5b505050506040513d6020811015611a7557600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f38a631830000000000000000000000000000000000000000000000000000000081529051602093840193928716926338a631839260048082019391829003018186803b158015611ae557600080fd5b505afa158015611af9573d6000803e3d6000fd5b505050506040513d6020811015611b0f57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff9081168252604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160209384019392871692635c975abb9260048082019391829003018186803b158015611b7f57600080fd5b505afa158015611b93573d6000803e3d6000fd5b505050506040513d6020811015611ba957600080fd5b505115158152604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8716926318160ddd9260048083019392829003018186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d6020811015611c4157600080fd5b505190529050611c518382612910565b611ca6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612db56022913960400191505060405180910390fd5b60066040518082805460018160011615610100020316600290048015611d035780601f10611ce1576101008083540402835291820191611d03565b820191906000526020600020905b815481529060010190602001808311611cef575b505091505060405180910390208273ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611d5657600080fd5b505afa158015611d6a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015611db157600080fd5b8101908080516040519392919084640100000000821115611dd157600080fd5b908301906020820185811115611de657600080fd5b8251640100000000811182820188101715611e0057600080fd5b82525081516020918201929091019080838360005b83811015611e2d578181015183820152602001611e15565b50505050905090810190601f168015611e5a5780820380516001836020036101000a031916815260200191505b506040525050508051906020012014611ed457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f56325f3255706772616465723a2073796d626f6c206e6f742075706461746564604482015290519081900360640190fd5b848273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611f3c57600080fd5b505afa158015611f50573d6000803e3d6000fd5b505050506040513d6020811015611f6657600080fd5b505114611fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612d4a6023913960400191505060405180910390fd5b604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152620186a06024820152905173ffffffffffffffffffffffffffffffffffffffff84169163a9059cbb9160448083019260209291908290030181600087803b15801561203557600080fd5b505af1158015612049573d6000803e3d6000fd5b505050506040513d602081101561205f57600080fd5b5051801561210f575061207584620186a0612b0d565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b1580156120e157600080fd5b505afa1580156120f5573d6000803e3d6000fd5b505050506040513d602081101561210b57600080fd5b5051145b80156121bd575061212385620186a0612b81565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561218f57600080fd5b505afa1580156121a3573d6000803e3d6000fd5b505050506040513d60208110156121b957600080fd5b5051145b612212576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612d286022913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663095ea7b387620186a06040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561228657600080fd5b505af115801561229a573d6000803e3d6000fd5b505050506040513d60208110156122b057600080fd5b505180156123615750604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff888116602483015291519184169163dd62ed3e91604480820192602092909190829003018186803b15801561232f57600080fd5b505afa158015612343573d6000803e3d6000fd5b505050506040513d602081101561235957600080fd5b5051620186a0145b80156124125750604080517f23b872dd000000000000000000000000000000000000000000000000000000008152306004820152336024820152620186a06044820152905173ffffffffffffffffffffffffffffffffffffffff8816916323b872dd9160648083019260209291908290030181600087803b1580156123e557600080fd5b505af11580156123f9573d6000803e3d6000fd5b505050506040513d602081101561240f57600080fd5b50515b80156124b95750604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152306004820152336024820152905173ffffffffffffffffffffffffffffffffffffffff84169163dd62ed3e916044808301926020929190829003018186803b15801561248b57600080fd5b505afa15801561249f573d6000803e3d6000fd5b505050506040513d60208110156124b557600080fd5b5051155b801561256757506124cd8462030d40612b0d565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561253957600080fd5b505afa15801561254d573d6000803e3d6000fd5b505050506040513d602081101561256357600080fd5b5051145b8015612615575061257b8562030d40612b81565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b1580156125e757600080fd5b505afa1580156125fb573d6000803e3d6000fd5b505050506040513d602081101561261157600080fd5b5051145b61266a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612dd7602e913960400191505060405180910390fd5b612672610244565b61267a612bf8565b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461270857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600154600354604080517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015290519190921691638f28397091602480830192600092919082900301818387803b15801561277f57600080fd5b505af1158015612793573d6000803e3d6000fd5b5050505061279f612bf8565b565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff16331461284357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166128af576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612d6d6026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a161290d81612c7d565b50565b60008160000151805190602001208360000151805190602001201480156129445750816020015160ff16836020015160ff16145b80156129655750816040015180519060200120836040015180519060200120145b80156129865750816060015180519060200120836060015180519060200120145b8015612999575081608001518360800151145b80156129d857508160a0015173ffffffffffffffffffffffffffffffffffffffff168360a0015173ffffffffffffffffffffffffffffffffffffffff16145b8015612a1757508160c0015173ffffffffffffffffffffffffffffffffffffffff168360c0015173ffffffffffffffffffffffffffffffffffffffff16145b8015612a5657508160e0015173ffffffffffffffffffffffffffffffffffffffff168360e0015173ffffffffffffffffffffffffffffffffffffffff16145b8015612a97575081610100015173ffffffffffffffffffffffffffffffffffffffff1683610100015173ffffffffffffffffffffffffffffffffffffffff16145b8015612ad8575081610120015173ffffffffffffffffffffffffffffffffffffffff1683610120015173ffffffffffffffffffffffffffffffffffffffff16145b8015612af1575081610140015115158361014001511515145b8015612b065750816101600151836101600151145b9392505050565b600082820183811015612b0657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082821115612bf257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60048054604080517fec1e6a4f000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169263ec1e6a4f92828201926000929082900301818387803b158015612c6157600080fd5b505af1158015612c75573d6000803e3d6000fd5b503392505050ff5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60408051610180810182526060808252600060208301819052928201819052808201526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101919091529056fe56325f3255706772616465723a207472616e736665722074657374206661696c656456325f3255706772616465723a2062616c616e63654f662074657374206661696c65644f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737356325f3255706772616465723a20302e322046696174546f6b656e206e656564656456325f3255706772616465723a206d657461646174612074657374206661696c656456325f3255706772616465723a20617070726f76652f7472616e7366657246726f6d2074657374206661696c6564a26469706673582212204819915d274abf3d15a3786f32e333cd2999420e94d010d1542e76b4cfa573f564736f6c634300060c0033",
+ "calls": [
+ {
+ "from": "0x9999fa87f5a1d1c64e7c709838b92006ab0cc1ad",
+ "gas": "0xd9acda",
+ "gasUsed": "0xbbe58",
+ "to": "0x4b2194b42ef7f4a41ba4ca3df6d1e140dc9972b2",
+ "input": "0x608060405234801561001057600080fd5b50604051610ebf380380610ebf8339818101604052602081101561003357600080fd5b5051808061004033610068565b600180546001600160a01b0319166001600160a01b03929092169190911790555061008a9050565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b610e26806100996000396000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80636d3c5bbe116100cd578063bd10243011610081578063ec1e6a4f11610066578063ec1e6a4f14610316578063ec55688914610320578063f2fde38b1461032857610151565b8063bd10243014610306578063e5a6b10f1461030e57610151565b80638da5cb5b116100b25780638da5cb5b146102ee57806395d89b41146102f65780639fd0506d146102fe57610151565b80636d3c5bbe146102b357806370a08231146102bb57610151565b806335d99f351161012457806338a631831161010957806338a631831461029b57806354fd4d50146102a35780635c975abb146102ab57610151565b806335d99f35146102625780633644e5151461029357610151565b806306fdde031461015657806318160ddd146101d357806323b872dd146101ed578063313ce56714610244575b600080fd5b61015e61035b565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610198578181015183820152602001610180565b50505050905090810190601f1680156101c55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101db6104d6565b60408051918252519081900360200190f35b6102306004803603606081101561020357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610572565b604080519115158252519081900360200190f35b61024c61062d565b6040805160ff9092168252519081900360200190f35b61026a610698565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6101db610703565b61026a61076e565b61015e6107d9565b610230610844565b61026a6108af565b6101db600480360360208110156102d157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661091a565b61026a6109c3565b61015e6109df565b61026a610a4a565b61026a610ab5565b61015e610b20565b61031e610b8b565b005b61026a610c14565b61031e6004803603602081101561033e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c30565b600154604080517f06fdde03000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916306fdde03916004808301926000929190829003018186803b1580156103c657600080fd5b505afa1580156103da573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561042157600080fd5b810190808051604051939291908464010000000082111561044157600080fd5b90830190602082018581111561045657600080fd5b825164010000000081118282018810171561047057600080fd5b82525081516020918201929091019080838360005b8381101561049d578181015183820152602001610485565b50505050905090810190601f1680156104ca5780820380516001836020036101000a031916815260200191505b50604052505050905090565b600154604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916318160ddd916004808301926020929190829003018186803b15801561054157600080fd5b505afa158015610555573d6000803e3d6000fd5b505050506040513d602081101561056b57600080fd5b5051905090565b600154604080517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015260448201859052915160009392909216916323b872dd9160648082019260209290919082900301818787803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050506040513d602081101561062357600080fd5b5051949350505050565b600154604080517f313ce567000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163313ce567916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916335d99f35916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f3644e515000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691633644e515916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f38a63183000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916338a63183916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f54fd4d50000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916354fd4d50916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691638da5cb5b916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152915160009392909216916370a0823191602480820192602092909190829003018186803b15801561099157600080fd5b505afa1580156109a5573d6000803e3d6000fd5b505050506040513d60208110156109bb57600080fd5b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600154604080517f95d89b41000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916395d89b41916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691639fd0506d916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fbd102430000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163bd102430916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff169163e5a6b10f916004808301926000929190829003018186803b1580156103c657600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610c1157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b33ff5b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cb657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610dcb6026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a1610d8081610d83565b50565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220383c813e998c1388f31580a958b4ef51a545c3007a0be737f82b32515a060b0d64736f6c634300060c0033000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
+ "output": "0x608060405234801561001057600080fd5b50600436106101515760003560e01c80636d3c5bbe116100cd578063bd10243011610081578063ec1e6a4f11610066578063ec1e6a4f14610316578063ec55688914610320578063f2fde38b1461032857610151565b8063bd10243014610306578063e5a6b10f1461030e57610151565b80638da5cb5b116100b25780638da5cb5b146102ee57806395d89b41146102f65780639fd0506d146102fe57610151565b80636d3c5bbe146102b357806370a08231146102bb57610151565b806335d99f351161012457806338a631831161010957806338a631831461029b57806354fd4d50146102a35780635c975abb146102ab57610151565b806335d99f35146102625780633644e5151461029357610151565b806306fdde031461015657806318160ddd146101d357806323b872dd146101ed578063313ce56714610244575b600080fd5b61015e61035b565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610198578181015183820152602001610180565b50505050905090810190601f1680156101c55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101db6104d6565b60408051918252519081900360200190f35b6102306004803603606081101561020357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610572565b604080519115158252519081900360200190f35b61024c61062d565b6040805160ff9092168252519081900360200190f35b61026a610698565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6101db610703565b61026a61076e565b61015e6107d9565b610230610844565b61026a6108af565b6101db600480360360208110156102d157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661091a565b61026a6109c3565b61015e6109df565b61026a610a4a565b61026a610ab5565b61015e610b20565b61031e610b8b565b005b61026a610c14565b61031e6004803603602081101561033e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c30565b600154604080517f06fdde03000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916306fdde03916004808301926000929190829003018186803b1580156103c657600080fd5b505afa1580156103da573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561042157600080fd5b810190808051604051939291908464010000000082111561044157600080fd5b90830190602082018581111561045657600080fd5b825164010000000081118282018810171561047057600080fd5b82525081516020918201929091019080838360005b8381101561049d578181015183820152602001610485565b50505050905090810190601f1680156104ca5780820380516001836020036101000a031916815260200191505b50604052505050905090565b600154604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916318160ddd916004808301926020929190829003018186803b15801561054157600080fd5b505afa158015610555573d6000803e3d6000fd5b505050506040513d602081101561056b57600080fd5b5051905090565b600154604080517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015260448201859052915160009392909216916323b872dd9160648082019260209290919082900301818787803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050506040513d602081101561062357600080fd5b5051949350505050565b600154604080517f313ce567000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163313ce567916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916335d99f35916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f3644e515000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691633644e515916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f38a63183000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916338a63183916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f54fd4d50000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916354fd4d50916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691638da5cb5b916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152915160009392909216916370a0823191602480820192602092909190829003018186803b15801561099157600080fd5b505afa1580156109a5573d6000803e3d6000fd5b505050506040513d60208110156109bb57600080fd5b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600154604080517f95d89b41000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916395d89b41916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691639fd0506d916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fbd102430000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163bd102430916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff169163e5a6b10f916004808301926000929190829003018186803b1580156103c657600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610c1157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b33ff5b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cb657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610dcb6026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a1610d8081610d83565b50565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220383c813e998c1388f31580a958b4ef51a545c3007a0be737f82b32515a060b0d64736f6c634300060c0033",
+ "value": "0x0",
+ "type": "CREATE"
+ }
+ ],
+ "value": "0x0",
+ "type": "CREATE"
+}
diff --git a/test/scripts/hardhat/testData/V2_2UpgraderHelperCreationBytecode.bin b/test/scripts/hardhat/testData/V2_2UpgraderHelperCreationBytecode.bin
new file mode 100644
index 000000000..9fb244bc1
--- /dev/null
+++ b/test/scripts/hardhat/testData/V2_2UpgraderHelperCreationBytecode.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50604051610ebf380380610ebf8339818101604052602081101561003357600080fd5b5051808061004033610068565b600180546001600160a01b0319166001600160a01b03929092169190911790555061008a9050565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b610e26806100996000396000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80636d3c5bbe116100cd578063bd10243011610081578063ec1e6a4f11610066578063ec1e6a4f14610316578063ec55688914610320578063f2fde38b1461032857610151565b8063bd10243014610306578063e5a6b10f1461030e57610151565b80638da5cb5b116100b25780638da5cb5b146102ee57806395d89b41146102f65780639fd0506d146102fe57610151565b80636d3c5bbe146102b357806370a08231146102bb57610151565b806335d99f351161012457806338a631831161010957806338a631831461029b57806354fd4d50146102a35780635c975abb146102ab57610151565b806335d99f35146102625780633644e5151461029357610151565b806306fdde031461015657806318160ddd146101d357806323b872dd146101ed578063313ce56714610244575b600080fd5b61015e61035b565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610198578181015183820152602001610180565b50505050905090810190601f1680156101c55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101db6104d6565b60408051918252519081900360200190f35b6102306004803603606081101561020357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610572565b604080519115158252519081900360200190f35b61024c61062d565b6040805160ff9092168252519081900360200190f35b61026a610698565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6101db610703565b61026a61076e565b61015e6107d9565b610230610844565b61026a6108af565b6101db600480360360208110156102d157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661091a565b61026a6109c3565b61015e6109df565b61026a610a4a565b61026a610ab5565b61015e610b20565b61031e610b8b565b005b61026a610c14565b61031e6004803603602081101561033e57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c30565b600154604080517f06fdde03000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916306fdde03916004808301926000929190829003018186803b1580156103c657600080fd5b505afa1580156103da573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561042157600080fd5b810190808051604051939291908464010000000082111561044157600080fd5b90830190602082018581111561045657600080fd5b825164010000000081118282018810171561047057600080fd5b82525081516020918201929091019080838360005b8381101561049d578181015183820152602001610485565b50505050905090810190601f1680156104ca5780820380516001836020036101000a031916815260200191505b50604052505050905090565b600154604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916318160ddd916004808301926020929190829003018186803b15801561054157600080fd5b505afa158015610555573d6000803e3d6000fd5b505050506040513d602081101561056b57600080fd5b5051905090565b600154604080517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152858116602483015260448201859052915160009392909216916323b872dd9160648082019260209290919082900301818787803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050506040513d602081101561062357600080fd5b5051949350505050565b600154604080517f313ce567000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163313ce567916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f35d99f35000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916335d99f35916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f3644e515000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691633644e515916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f38a63183000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916338a63183916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f54fd4d50000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916354fd4d50916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691638da5cb5b916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152915160009392909216916370a0823191602480820192602092909190829003018186803b15801561099157600080fd5b505afa1580156109a5573d6000803e3d6000fd5b505050506040513d60208110156109bb57600080fd5b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600154604080517f95d89b41000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff16916395d89b41916004808301926000929190829003018186803b1580156103c657600080fd5b600154604080517f9fd0506d000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691639fd0506d916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fbd102430000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163bd102430916004808301926020929190829003018186803b15801561054157600080fd5b600154604080517fe5a6b10f000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff169163e5a6b10f916004808301926000929190829003018186803b1580156103c657600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610c1157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b33ff5b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cb657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610dcb6026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a1610d8081610d83565b50565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220383c813e998c1388f31580a958b4ef51a545c3007a0be737f82b32515a060b0d64736f6c634300060c0033000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
\ No newline at end of file
diff --git a/test/scripts/hardhat/verifyOnChainBytecode.test.ts b/test/scripts/hardhat/verifyOnChainBytecode.test.ts
new file mode 100644
index 000000000..f701fd92c
--- /dev/null
+++ b/test/scripts/hardhat/verifyOnChainBytecode.test.ts
@@ -0,0 +1,314 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import hre from "hardhat";
+import * as fs from "fs";
+import * as sinon from "sinon";
+import {
+ verifyOnChainBytecode,
+ BytecodeInputType,
+ BytecodeVerificationType,
+ extractBytecodeFromGethTraces,
+} from "../../../scripts/hardhat/verifyOnChainBytecode";
+import { BaseContract, Contract, ContractTransactionResponse } from "ethers";
+import { mkdirSync, writeFileSync } from "fs";
+import { HARDHAT_ACCOUNTS } from "../../helpers/constants";
+import {
+ ArtifactType,
+ opMainnetFiatTokenProxyContractCreationBytecode,
+} from "../../../scripts/hardhat/alternativeArtifacts";
+import V2_2UpgraderDeploymentTrace from "./testData/V2_2UpgraderDeploymentTrace.json";
+import * as Helpers from "../../../scripts/hardhat/helpers";
+
+describe("Verify on chain bytecode", () => {
+ let proxy: Contract;
+ let v22: Contract;
+ let signatureChecker: Contract;
+ let opMainnetArtifactFiatTokenProxy: BaseContract & {
+ deploymentTransaction(): ContractTransactionResponse;
+ };
+ let execSyncWrapperStub: sinon.SinonStub<[string], void>;
+
+ before("setup", async () => {
+ signatureChecker = await hre.ethers.deployContract("SignatureChecker");
+ const FiatTokenV2_2 = await hre.ethers.getContractFactory("FiatTokenV2_2", {
+ signer: await hre.ethers.getSigner(HARDHAT_ACCOUNTS[0]),
+ libraries: { SignatureChecker: signatureChecker.target },
+ });
+ v22 = await FiatTokenV2_2.deploy();
+ proxy = await hre.ethers.deployContract("FiatTokenProxy", [v22.target]);
+
+ // deploy a contract using the OP Mainnet artifact
+ const opMainnetFiatTokenProxyFactory = new hre.ethers.ContractFactory(
+ [],
+ opMainnetFiatTokenProxyContractCreationBytecode.slice(0, -40) +
+ (await v22.getAddress()).slice(2),
+ await hre.ethers.getSigner(HARDHAT_ACCOUNTS[0])
+ );
+ opMainnetArtifactFiatTokenProxy = await opMainnetFiatTokenProxyFactory.deploy();
+ await opMainnetArtifactFiatTokenProxy.waitForDeployment();
+ });
+
+ beforeEach(() => {
+ execSyncWrapperStub = sinon.stub(Helpers, "execSyncWrapper");
+ });
+
+ afterEach(() => {
+ sinon.restore();
+ });
+
+ it("rejects for an improper optimizerRuns", async () => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const improperOptimizerRuns: any[] = ["&& do something", 1.1, -1, "1000"];
+
+ for (const improperOptimizerRun in improperOptimizerRuns) {
+ await expect(
+ verifyOnChainBytecode(
+ {
+ contractName: "FiatTokenProxy",
+ contractAddress: proxy.target as string,
+ verificationType: BytecodeVerificationType.Partial,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ optimizerRuns: improperOptimizerRun as any,
+ },
+ hre
+ )
+ ).to.be.rejectedWith("invalid optimizerRuns");
+ }
+ });
+
+ it("will execute the expected forge command when optimizerRuns is present", async () => {
+ const results = await verifyOnChainBytecode(
+ {
+ contractName: "FiatTokenProxy",
+ contractAddress: proxy.target as string,
+ verificationType: BytecodeVerificationType.Partial,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ optimizerRuns: 1000,
+ },
+ hre
+ );
+
+ expect(results).to.deep.equal([
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: true },
+ ]);
+
+ expect(
+ execSyncWrapperStub.calledOnceWithExactly(
+ "forge build --optimizer-runs 1000"
+ )
+ ).to.be.true;
+ });
+
+ it("Can detect mismatched metadata input", async () => {
+ const results = await verifyOnChainBytecode(
+ {
+ contractName: "FiatTokenProxy",
+ contractAddress: proxy.target as string,
+ verificationType: BytecodeVerificationType.Partial,
+ metadataFilePath:
+ // Contains mismatched metadata (auto generated by foundry instead of hardhat)
+ "test/scripts/hardhat/testData/FiatTokenProxy.metadata.json",
+ },
+ hre
+ );
+
+ expect(results).to.deep.equal([
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: true },
+ { type: BytecodeInputType.MetadataHash, equal: false },
+ ]);
+ });
+
+ it("Can detect mismatched constructor code", async () => {
+ expect(
+ await verifyOnChainBytecode(
+ {
+ contractName: "FiatTokenProxy",
+ contractAddress: proxy.target as string,
+ verificationType: BytecodeVerificationType.Partial,
+ contractCreationTxHash: v22.deploymentTransaction()?.hash, // Wrong transaction hash supplied
+ },
+ hre
+ )
+ ).to.deep.equal([
+ { type: BytecodeInputType.ConstructorCode, equal: false },
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: true },
+ ]);
+ });
+
+ it("Can detect mismatched runtime code", async () => {
+ expect(
+ await verifyOnChainBytecode(
+ {
+ contractName: "FiatTokenProxy",
+ contractAddress: v22.target as string, // Wrong contract address supplied
+ verificationType: BytecodeVerificationType.Partial,
+ },
+ hre
+ )
+ ).to.deep.equal([
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: false },
+ ]);
+ });
+
+ it("Can run partial verification on valid FiatTokenProxy contract", async () => {
+ const contractName = "FiatTokenProxy";
+ const contractDir = "contracts/v1/FiatTokenProxy.sol";
+ const metadataPath = await prepareMetadata(contractName, contractDir);
+
+ const results = await verifyOnChainBytecode(
+ {
+ contractName,
+ contractAddress: proxy.target as string,
+ verificationType: BytecodeVerificationType.Partial,
+ metadataFilePath: metadataPath,
+ contractCreationTxHash: proxy.deploymentTransaction()?.hash,
+ },
+ hre
+ );
+
+ expect(results).to.deep.equal([
+ { type: BytecodeInputType.ConstructorCode, equal: true },
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: true },
+ { type: BytecodeInputType.MetadataHash, equal: true },
+ ]);
+ });
+
+ it("Can run partial verification on valid FiatTokenV2_2 contract", async () => {
+ const contractName = "FiatTokenV2_2";
+ const contractDir = "contracts/v2/FiatTokenV2_2.sol";
+ const metadataPath = await prepareMetadata(contractName, contractDir);
+
+ const results = await verifyOnChainBytecode(
+ {
+ contractName,
+ contractAddress: v22.target as string,
+ libraryName: "SignatureChecker",
+ libraryAddress: signatureChecker.target as string,
+ verificationType: BytecodeVerificationType.Partial,
+ metadataFilePath: metadataPath,
+ contractCreationTxHash: v22.deploymentTransaction()?.hash,
+ },
+ hre
+ );
+
+ expect(results).to.deep.equal([
+ { type: BytecodeInputType.ConstructorCode, equal: true },
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: true },
+ { type: BytecodeInputType.MetadataHash, equal: true },
+ ]);
+ });
+
+ it("Can run partial verification on valid SignatureChecker contract", async () => {
+ const contractName = "SignatureChecker";
+ const contractDir = "contracts/util/SignatureChecker.sol";
+ const metadataPath = await prepareMetadata(contractName, contractDir);
+
+ const results = await verifyOnChainBytecode(
+ {
+ contractName,
+ contractAddress: signatureChecker.target as string,
+ verificationType: BytecodeVerificationType.Partial,
+ isLibrary: true,
+ metadataFilePath: metadataPath,
+ contractCreationTxHash: signatureChecker.deploymentTransaction()?.hash,
+ },
+ hre
+ );
+
+ expect(results).to.deep.equal([
+ { type: BytecodeInputType.ConstructorCode, equal: true },
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: true },
+ { type: BytecodeInputType.MetadataHash, equal: true },
+ ]);
+ });
+
+ it("Can run partial verification with bytecode input from a file", async () => {
+ expect(
+ await verifyOnChainBytecode(
+ {
+ contractName: "FiatTokenProxy",
+ contractAddress: proxy.target as string,
+ onchainBytecodeFilePath:
+ // Contains deployed bytecode from `artifacts/foundry/FiatTokenProxy.sol/FiatTokenProxy.json`, `
+ "test/scripts/hardhat/testData/FiatTokenProxy.bin",
+ verificationType: BytecodeVerificationType.Partial,
+ },
+ hre
+ )
+ ).to.deep.equal([
+ { type: BytecodeInputType.RuntimeBytecodePartial, equal: true },
+ ]);
+ });
+
+ it("Can use an alternative artifact for verification", async () => {
+ expect(
+ await verifyOnChainBytecode(
+ {
+ contractName: "FiatTokenProxy",
+ contractAddress: await opMainnetArtifactFiatTokenProxy.getAddress(),
+ verificationType: BytecodeVerificationType.Full,
+ artifactType: ArtifactType.OPMainnet,
+ contractCreationTxHash: opMainnetArtifactFiatTokenProxy.deploymentTransaction()
+ ?.hash,
+ },
+ hre
+ )
+ ).to.deep.equal([
+ { type: BytecodeInputType.ConstructorCode, equal: true },
+ { type: BytecodeInputType.RuntimeBytecodeFull, equal: true },
+ ]);
+ });
+
+ it("Can pull contract creation code from traces", async () => {
+ // example contract creation from internal transaction taken from: https://etherscan.io/tx/0x7f6268ff5bd05d1b61c19889a46eb9a38563accce441dcfcf0c7515b1733503e
+ // it's the deployment of the UpgraderHelper contract for V2_2Upgrader.sol
+ const expectedCreationBytecode =
+ "0x" +
+ fs.readFileSync(
+ "test/scripts/hardhat/testData/V2_2UpgraderHelperCreationBytecode.bin",
+ "utf-8"
+ );
+ const contractAddress = "0x4b2194B42EF7F4A41BA4cA3Df6D1E140dc9972b2";
+ expect(
+ extractBytecodeFromGethTraces(
+ V2_2UpgraderDeploymentTrace,
+ contractAddress
+ )
+ ).to.deep.equal(expectedCreationBytecode);
+ });
+});
+
+async function prepareMetadata(
+ contractName: string,
+ contractDir: string
+): Promise {
+ const buildInfo = await hre.artifacts.getBuildInfo(
+ `${contractDir}:${contractName}`
+ );
+ const complierContractOutput = buildInfo?.output.contracts[contractDir][
+ contractName
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ ] as any;
+
+ const dirPath = `artifacts/test/${contractDir}`;
+ const metadataPath = `${dirPath}/${contractName}.metadata.json`;
+ mkdirSync(dirPath, { recursive: true });
+ writeFileSync(metadataPath, complierContractOutput.metadata, null);
+ return metadataPath;
+}
diff --git a/test/util/ECRecover.test.ts b/test/util/ECRecover.test.ts
index 31a13784a..75709c235 100644
--- a/test/util/ECRecover.test.ts
+++ b/test/util/ECRecover.test.ts
@@ -1,69 +1,109 @@
-import { ecSign, expectRevert } from "../helpers";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { bufferFromHexString, ecSign, expectRevert } from "../helpers";
import { ACCOUNTS_AND_KEYS, ZERO_BYTES32 } from "../helpers/constants";
-import { EcRecoverTestInstance } from "../../@types/generated/EcRecoverTest";
+import { ECRecoverTestInstance } from "../../@types/generated";
+import { packSig } from "./SignatureChecker.test";
+import { toCompactSig } from "ethereumjs-util";
const ECRecoverTest = artifacts.require("ECRecoverTest");
-contract("ECRecover", (_accounts) => {
- let ecRecover: EcRecoverTestInstance;
+describe("ECRecover", () => {
+ const digest = web3.utils.keccak256("Hello world!");
+ const [account1, account2, account3] = ACCOUNTS_AND_KEYS;
+ const sig1 = ecSign(digest, account1.key);
+ const sig2 = ecSign(digest, account2.key);
+ const sig3 = ecSign(digest, account3.key);
+
+ let ecRecover: ECRecoverTestInstance;
beforeEach(async () => {
ecRecover = await ECRecoverTest.new();
});
-
describe("recover", () => {
- const digest = web3.utils.keccak256("Hello world!");
- const [account1, account2, account3] = ACCOUNTS_AND_KEYS;
- const sig1 = ecSign(digest, account1.key);
- const sig2 = ecSign(digest, account2.key);
- const sig3 = ecSign(digest, account3.key);
-
it("recovers signer address from a valid signature", async () => {
expect(sig1).not.to.deep.equal(sig2);
expect(sig1).not.to.deep.equal(sig3);
expect(sig2).not.to.deep.equal(sig3);
- expect(await ecRecover.recover(digest, sig1.v, sig1.r, sig1.s)).to.equal(
+ expect(await ecRecover.recover(digest, packSig(sig1))).to.equal(
account1.address
);
- expect(await ecRecover.recover(digest, sig2.v, sig2.r, sig2.s)).to.equal(
+ expect(await ecRecover.recover(digest, packSig(sig2))).to.equal(
account2.address
);
- expect(await ecRecover.recover(digest, sig3.v, sig3.r, sig3.s)).to.equal(
+ expect(await ecRecover.recover(digest, packSig(sig3))).to.equal(
account3.address
);
});
it("reverts if an invalid signature is given", async () => {
await expectRevert(
- ecRecover.recover(digest, 27, ZERO_BYTES32, ZERO_BYTES32),
+ ecRecover.recover(
+ digest,
+ packSig({ v: 27, r: ZERO_BYTES32, s: ZERO_BYTES32 })
+ ),
"invalid signature"
);
});
it("reverts if an invalid v value is given", async () => {
await expectRevert(
- ecRecover.recover(digest, sig1.v - 2, sig1.r, sig1.s),
+ ecRecover.recover(
+ digest,
+ packSig({ v: sig1.v - 2, r: sig1.r, s: sig1.s })
+ ),
"invalid signature 'v' value"
);
await expectRevert(
- ecRecover.recover(digest, sig2.v - 2, sig2.r, sig2.s),
+ ecRecover.recover(
+ digest,
+ packSig({ v: sig2.v - 2, r: sig2.r, s: sig2.s })
+ ),
"invalid signature 'v' value"
);
await expectRevert(
- ecRecover.recover(digest, sig3.v - 2, sig3.r, sig3.s),
+ ecRecover.recover(
+ digest,
+ packSig({ v: sig3.v - 2, r: sig3.r, s: sig3.s })
+ ),
"invalid signature 'v' value"
);
await expectRevert(
- ecRecover.recover(digest, sig1.v + 2, sig1.r, sig1.s),
+ ecRecover.recover(
+ digest,
+ packSig({ v: sig1.v + 2, r: sig1.r, s: sig1.s })
+ ),
"invalid signature 'v' value"
);
await expectRevert(
- ecRecover.recover(digest, sig2.v + 2, sig2.r, sig2.s),
+ ecRecover.recover(
+ digest,
+ packSig({ v: sig2.v + 2, r: sig2.r, s: sig2.s })
+ ),
"invalid signature 'v' value"
);
await expectRevert(
- ecRecover.recover(digest, sig3.v + 2, sig3.r, sig3.s),
+ ecRecover.recover(
+ digest,
+ packSig({ v: sig3.v + 2, r: sig3.r, s: sig3.s })
+ ),
"invalid signature 'v' value"
);
});
@@ -78,9 +118,22 @@ contract("ECRecover", (_accounts) => {
"0xe0a0fc89be718fbc1033e1d30d78be1c68081562ed2e97af876f286f3453231d";
await expectRevert(
- ecRecover.recover(dig, v, r, s),
+ ecRecover.recover(dig, packSig({ v, r, s })),
"invalid signature 's' value"
);
});
+
+ it("reverts if signature has incorrect length", async () => {
+ const compactSig: string = toCompactSig(
+ sig1.v,
+ bufferFromHexString(sig1.r),
+ bufferFromHexString(sig1.s)
+ );
+
+ await expectRevert(
+ ecRecover.recover(digest, compactSig),
+ "invalid signature length"
+ );
+ });
});
});
diff --git a/test/util/EIP712Test.ts b/test/util/EIP712Test.ts
index dde4a9513..9f88f80c5 100644
--- a/test/util/EIP712Test.ts
+++ b/test/util/EIP712Test.ts
@@ -1,14 +1,30 @@
-import crypto from "crypto";
-import { Eip712TestInstance } from "../../@types/generated";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { EIP712TestInstance } from "../../@types/generated";
import { wordlist } from "ethereum-cryptography/bip39/wordlists/english";
import sampleSize from "lodash/sampleSize";
-import { ACCOUNTS_AND_KEYS } from "../helpers/constants";
-import { prepend0x, strip0x, ecSign } from "../helpers";
+import { makeDomainSeparator } from "../helpers";
const EIP712Test = artifacts.require("EIP712Test");
-contract("EIP712", (_accounts) => {
- let eip712: Eip712TestInstance;
+describe("EIP712", () => {
+ let eip712: EIP712TestInstance;
let chainId: number;
let randomName: string;
let randomVersion: string;
@@ -16,11 +32,7 @@ contract("EIP712", (_accounts) => {
beforeEach(async () => {
eip712 = await EIP712Test.new();
-
- // hardcode chainId to be 1 due to ganache bug
- // https://github.com/trufflesuite/ganache/issues/1643
- // chainId = await web3.eth.getChainId();
- chainId = 1;
+ chainId = await web3.eth.getChainId();
randomName = sampleSize(wordlist, 3).join(" ");
randomVersion = (Math.floor(Math.random() * 10) + 1).toString();
@@ -39,48 +51,4 @@ contract("EIP712", (_accounts) => {
).to.equal(domainSeparator);
});
});
-
- describe("recover", () => {
- it("recovers the signer's address from signed data", async () => {
- const randomAccount =
- ACCOUNTS_AND_KEYS[Math.floor(Math.random() * ACCOUNTS_AND_KEYS.length)];
- const randomData = prepend0x(crypto.randomBytes(256).toString("hex"));
- const eip712Data = prepend0x(
- "1901" +
- strip0x(domainSeparator) +
- strip0x(web3.utils.keccak256(randomData))
- );
-
- const { v, r, s } = ecSign(
- web3.utils.keccak256(eip712Data),
- randomAccount.key
- );
-
- expect(
- await eip712.recover(domainSeparator, v, r, s, randomData)
- ).to.equal(randomAccount.address);
- });
- });
});
-
-function makeDomainSeparator(
- name: string,
- version: string,
- chainId: number,
- address: string
-): string {
- return web3.utils.keccak256(
- web3.eth.abi.encodeParameters(
- ["bytes32", "bytes32", "bytes32", "uint256", "address"],
- [
- web3.utils.keccak256(
- "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
- ),
- web3.utils.keccak256(name),
- web3.utils.keccak256(version),
- chainId,
- address,
- ]
- )
- );
-}
diff --git a/test/util/MessageHashUtils.test.ts b/test/util/MessageHashUtils.test.ts
new file mode 100644
index 000000000..cea13f2d8
--- /dev/null
+++ b/test/util/MessageHashUtils.test.ts
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ bufferFromHexString,
+ hexStringFromBuffer,
+ makeDomainSeparator,
+} from "../helpers";
+import { MessageHashUtilsTestInstance } from "../../@types/generated";
+
+const MessageHashUtils = artifacts.require("MessageHashUtilsTest");
+
+describe("MessageHashUtils", function () {
+ context("toTypedDataHash", function () {
+ it("returns the digest correctly", async function () {
+ const messageHashUtils: MessageHashUtilsTestInstance = await MessageHashUtils.new();
+ const structhash: string = web3.utils.randomHex(32);
+ const domainSeparator: string = makeDomainSeparator(
+ "USDC",
+ "2",
+ 1,
+ messageHashUtils.address
+ );
+ expect(
+ await messageHashUtils.toTypedDataHash(domainSeparator, structhash)
+ ).to.equal(hashTypedData(domainSeparator, structhash));
+ });
+ });
+});
+
+function hashTypedData(domainSeparator: string, structHash: string): string {
+ return web3.utils.keccak256(
+ hexStringFromBuffer(
+ Buffer.concat(
+ ["0x1901", domainSeparator, structHash].map((str) =>
+ bufferFromHexString(str)
+ )
+ )
+ )
+ );
+}
diff --git a/test/util/SignatureChecker.test.ts b/test/util/SignatureChecker.test.ts
new file mode 100644
index 000000000..8e96249b7
--- /dev/null
+++ b/test/util/SignatureChecker.test.ts
@@ -0,0 +1,200 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ Signature,
+ ecSign,
+ hexStringFromBuffer,
+ packSignature,
+} from "../helpers";
+import {
+ ACCOUNTS_AND_KEYS,
+ ZERO_ADDRESS,
+ ZERO_BYTES32,
+} from "../helpers/constants";
+import {
+ MockERC1271WalletInstance,
+ MockERC1271WalletReturningBytes32Instance,
+ MockERC1271WalletWithCustomValidationInstance,
+ MockStateModifyingERC1271WalletInstance,
+ SignatureCheckerInstance,
+} from "../../@types/generated";
+
+const SignatureChecker = artifacts.require("SignatureChecker");
+const MockERC1271Wallet = artifacts.require("MockERC1271Wallet");
+const MockERC1271WalletReturningBytes32 = artifacts.require(
+ "MockERC1271WalletReturningBytes32"
+);
+const MockERC1271WalletWithCustomValidation = artifacts.require(
+ "MockERC1271WalletWithCustomValidation"
+);
+const MockStateModifyingERC1271Wallet = artifacts.require(
+ "MockStateModifyingERC1271Wallet"
+);
+
+describe("SignatureChecker", () => {
+ const digest = web3.utils.keccak256("Hello world!");
+ const [account1, account2, account3] = ACCOUNTS_AND_KEYS;
+ const sig1 = ecSign(digest, account1.key);
+ const sig2 = ecSign(digest, account2.key);
+ const sig3 = ecSign(digest, account3.key);
+
+ let signatureChecker: SignatureCheckerInstance;
+ let standardWallet: MockERC1271WalletInstance;
+ let walletReturningBytes32: MockERC1271WalletReturningBytes32Instance;
+ let customWallet: MockERC1271WalletWithCustomValidationInstance;
+ let stateModifyingWallet: MockStateModifyingERC1271WalletInstance;
+
+ beforeEach(async () => {
+ signatureChecker = await SignatureChecker.new();
+ standardWallet = await MockERC1271Wallet.new(account1.address);
+ walletReturningBytes32 = await MockERC1271WalletReturningBytes32.new();
+ customWallet = await MockERC1271WalletWithCustomValidation.new(
+ account1.address
+ );
+ stateModifyingWallet = await MockStateModifyingERC1271Wallet.new();
+ });
+
+ context("EOA Wallet", () => {
+ it("returns true when given a valid signature", async () => {
+ expect(sig1).not.to.deep.equal(sig2);
+ expect(sig1).not.to.deep.equal(sig3);
+ expect(sig2).not.to.deep.equal(sig3);
+
+ await expectValidSignature(account1.address, digest, packSig(sig1));
+ await expectValidSignature(account2.address, digest, packSig(sig2));
+ await expectValidSignature(account3.address, digest, packSig(sig3));
+ });
+
+ it("returns false when given a invalid signature", async () => {
+ expect(
+ await signatureChecker.isValidSignatureNow(
+ account1.address,
+ digest,
+ packSig(sig2)
+ )
+ ).to.equal(false);
+ });
+
+ it("returns false if signer is zero address", async () => {
+ expect(
+ await signatureChecker.isValidSignatureNow(
+ ZERO_ADDRESS,
+ digest,
+ packSig(sig1)
+ )
+ ).to.equal(false);
+ });
+ });
+
+ context("AA Wallet - standard", () => {
+ it("returns true when given a valid signature", async () => {
+ await expectValidSignature(standardWallet.address, digest, packSig(sig1));
+ });
+
+ it("returns false when given a invalid signature", async () => {
+ await expectInvalidSignature(
+ standardWallet.address,
+ digest,
+ packSig(sig2)
+ );
+ });
+ });
+
+ context("AA Wallet - walletReturningBytes32", () => {
+ it("returns false when given a signature", async () => {
+ await expectInvalidSignature(
+ walletReturningBytes32.address,
+ digest,
+ packSig(sig1)
+ );
+ });
+ });
+
+ context("AA Wallet - custom validation", () => {
+ it("returns true when wallet considers signature to be valid", async () => {
+ await customWallet.setSignatureValid(true);
+ await expectValidSignature(customWallet.address, ZERO_BYTES32, "0x0");
+ });
+
+ it("returns false when wallet considers signature to be invalid", async () => {
+ await customWallet.setSignatureValid(false);
+ await expectInvalidSignature(customWallet.address, ZERO_BYTES32, "0x0");
+ });
+ });
+
+ context("AA Wallet - state modifying", () => {
+ it("returns false for wallet contracts that omit the `view` modifier", async () => {
+ expect(await stateModifyingWallet.evoked()).to.equal(false);
+
+ await expectInvalidSignature(
+ stateModifyingWallet.address,
+ ZERO_BYTES32,
+ "0x0"
+ );
+
+ // isValidSignature inside mock wallet is never evoked
+ expect(await stateModifyingWallet.evoked()).to.equal(false);
+ });
+ });
+
+ async function expectSignatureValidationResult(
+ accountAddress: string,
+ digest: string,
+ signature: string,
+ expectValidSignature: boolean
+ ) {
+ expect(
+ await signatureChecker.isValidSignatureNow(
+ accountAddress,
+ digest,
+ signature
+ )
+ ).to.equal(expectValidSignature);
+ }
+
+ async function expectValidSignature(
+ accountAddress: string,
+ digest: string,
+ signature: string
+ ) {
+ await expectSignatureValidationResult(
+ accountAddress,
+ digest,
+ signature,
+ true
+ );
+ }
+
+ async function expectInvalidSignature(
+ accountAddress: string,
+ digest: string,
+ signature: string
+ ) {
+ await expectSignatureValidationResult(
+ accountAddress,
+ digest,
+ signature,
+ false
+ );
+ }
+});
+
+export function packSig(sig: Signature): string {
+ return hexStringFromBuffer(packSignature(sig));
+}
diff --git a/test/v1.1/FiatTokenV1_1.test.ts b/test/v1.1/FiatTokenV1_1.test.ts
index 82cf59dc0..00c94c01d 100644
--- a/test/v1.1/FiatTokenV1_1.test.ts
+++ b/test/v1.1/FiatTokenV1_1.test.ts
@@ -1,20 +1,40 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { behavesLikeRescuable } from "./Rescuable.behavior";
import {
- FiatTokenV11Instance,
+ FiatTokenV1_1Instance,
RescuableInstance,
} from "../../@types/generated";
import { usesOriginalStorageSlotPositions } from "../helpers/storageSlots.behavior";
+import { HARDHAT_ACCOUNTS } from "../helpers/constants";
const FiatTokenV1_1 = artifacts.require("FiatTokenV1_1");
-contract("FiatTokenV1_1", (accounts) => {
- let fiatToken: FiatTokenV11Instance;
+describe("FiatTokenV1_1", () => {
+ const owner = HARDHAT_ACCOUNTS[0];
+
+ let fiatToken: FiatTokenV1_1Instance;
beforeEach(async () => {
fiatToken = await FiatTokenV1_1.new();
- const owner = accounts[0];
await fiatToken.initialize(
- "USD Coin",
+ "USDC",
"USDC",
"USD",
6,
@@ -25,10 +45,9 @@ contract("FiatTokenV1_1", (accounts) => {
);
});
- behavesLikeRescuable(() => fiatToken as RescuableInstance, accounts);
+ behavesLikeRescuable(() => fiatToken as RescuableInstance);
usesOriginalStorageSlotPositions({
Contract: FiatTokenV1_1,
version: 1.1,
- accounts,
});
});
diff --git a/test/v1.1/Rescuable.behavior.ts b/test/v1.1/Rescuable.behavior.ts
index 1b1ad26c3..6e24a0095 100644
--- a/test/v1.1/Rescuable.behavior.ts
+++ b/test/v1.1/Rescuable.behavior.ts
@@ -1,14 +1,32 @@
-import { RescuableInstance } from "../../@types/generated/Rescuable";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { expectRevert } from "../helpers";
-import { DummyErc20Instance } from "../../@types/generated";
-import { ZERO_ADDRESS } from "../helpers/constants";
+import { DummyERC20Instance, RescuableInstance } from "../../@types/generated";
+import { HARDHAT_ACCOUNTS, ZERO_ADDRESS } from "../helpers/constants";
const DummyERC20 = artifacts.require("DummyERC20");
export function behavesLikeRescuable(
- getContract: () => RescuableInstance,
- accounts: Truffle.Accounts
+ getContract: () => RescuableInstance
): void {
describe("behaves like a Rescuable", () => {
+ const accounts = HARDHAT_ACCOUNTS;
+
let rescuable: RescuableInstance;
let owner: string;
@@ -40,15 +58,13 @@ export function behavesLikeRescuable(
});
describe("rescueERC20", () => {
- let rescuer: string;
- let tokenOwner: string;
- let token: DummyErc20Instance;
+ const rescuer = accounts[1];
+ const tokenOwner = accounts[14];
+
+ let token: DummyERC20Instance;
beforeEach(async () => {
- rescuer = accounts[1];
await rescuable.updateRescuer(rescuer, { from: owner });
-
- tokenOwner = accounts[14];
token = await DummyERC20.new("Dummy", "DUMB", 1000, {
from: tokenOwner,
});
diff --git a/test/v1.1/Rescuable.test.ts b/test/v1.1/Rescuable.test.ts
index 04d81252b..ac6869bf3 100644
--- a/test/v1.1/Rescuable.test.ts
+++ b/test/v1.1/Rescuable.test.ts
@@ -1,17 +1,35 @@
-import { RescuableInstance } from "../../@types/generated/Rescuable";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { RescuableInstance } from "../../@types/generated";
import { behavesLikeRescuable } from "./Rescuable.behavior";
import { ZERO_ADDRESS } from "../helpers/constants";
const Rescuable = artifacts.require("Rescuable");
-contract("Rescuable", (accounts) => {
+describe("Rescuable", () => {
let rescuable: RescuableInstance;
beforeEach(async () => {
rescuable = await Rescuable.new();
});
- behavesLikeRescuable(() => rescuable, accounts);
+ behavesLikeRescuable(() => rescuable);
it("initially sets rescuer to be the zero address", async () => {
const rescuer = await rescuable.rescuer();
diff --git a/test/v1/FiatTokenV1.test.ts b/test/v1/FiatTokenV1.test.ts
index 04eef0daf..e9413a169 100644
--- a/test/v1/FiatTokenV1.test.ts
+++ b/test/v1/FiatTokenV1.test.ts
@@ -1,11 +1,28 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { usesOriginalStorageSlotPositions } from "../helpers/storageSlots.behavior";
const FiatTokenV1 = artifacts.require("FiatTokenV1");
-contract("FiatTokenV1", (accounts) => {
+describe("FiatTokenV1", () => {
usesOriginalStorageSlotPositions({
Contract: FiatTokenV1,
version: 1,
- accounts,
});
});
diff --git a/test/v1/Pausable.test.js b/test/v1/Pausable.test.js
index ffd55650e..a6c0d0ab9 100644
--- a/test/v1/Pausable.test.js
+++ b/test/v1/Pausable.test.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const {
expectRevert,
deployerAccount,
@@ -7,7 +25,7 @@ const {
const Pausable = artifacts.require("Pausable");
-contract("Pausable", (_accounts) => {
+describe("Pausable", () => {
let pausable;
beforeEach(async () => {
diff --git a/test/v1/TokenTestUtils.js b/test/v1/TokenTestUtils.js
deleted file mode 100644
index 02224d005..000000000
--- a/test/v1/TokenTestUtils.js
+++ /dev/null
@@ -1,1047 +0,0 @@
-const util = require("util");
-const abi = require("ethereumjs-abi");
-const _ = require("lodash");
-const BN = require("bn.js");
-const Q = require("q");
-
-const FiatTokenV1 = artifacts.require("FiatTokenV1");
-const UpgradedFiatToken = artifacts.require("UpgradedFiatToken");
-const UpgradedFiatTokenNewFields = artifacts.require(
- "UpgradedFiatTokenNewFieldsTest"
-);
-const UpgradedFiatTokenNewFieldsNewLogic = artifacts.require(
- "UpgradedFiatTokenNewFieldsNewLogicTest"
-);
-const FiatTokenProxy = artifacts.require("FiatTokenProxy");
-
-const name = "Sample Fiat Token";
-const symbol = "C-USD";
-const currency = "USD";
-const decimals = 2;
-const trueInStorageFormat = "0x01";
-const bigZero = new BN(0);
-const bigHundred = new BN(100);
-
-// TODO: test really big numbers Does this still have to be done??
-
-const nullAccount = "0x0000000000000000000000000000000000000000";
-const deployerAccount = "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1"; // accounts[0]
-const arbitraryAccount = "0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0"; // accounts[1]
-const tokenOwnerAccount = "0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d"; // accounts[3]
-const blacklisterAccount = "0xd03ea8624C8C5987235048901fB614fDcA89b117"; // accounts[4]
-const arbitraryAccount2 = "0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC"; // accounts[5]
-const masterMinterAccount = "0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9"; // accounts[6]
-const minterAccount = "0x28a8746e75304c0780E011BEd21C72cD78cd535E"; // accounts[7]
-const pauserAccount = "0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E"; // accounts[8]
-
-const proxyOwnerAccount = "0x2F560290FEF1B3Ada194b6aA9c40aa71f8e95598"; // accounts[14]
-const upgraderAccount = proxyOwnerAccount; // accounts[14]
-
-const deployerAccountPrivateKey =
- "4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"; // accounts[0]
-const arbitraryAccountPrivateKey =
- "6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1"; // accounts[1];
-const tokenOwnerPrivateKey =
- "646f1ce2fdad0e6deeeb5c7e8e5543bdde65e86029e2fd9fc169899c440a7913"; // accounts[3]
-const blacklisterAccountPrivateKey =
- "add53f9a7e588d003326d1cbf9e4a43c061aadd9bc938c843a79e7b4fd2ad743"; // accounts[4]
-const arbitraryAccount2PrivateKey =
- "395df67f0c2d2d9fe1ad08d1bc8b6627011959b79c53d7dd6a3536a33ab8a4fd"; // accounts[5]
-const masterMinterAccountPrivateKey =
- "e485d098507f54e7733a205420dfddbe58db035fa577fc294ebd14db90767a52"; // accounts[6]
-const minterAccountPrivateKey =
- "a453611d9419d0e56f499079478fd72c37b251a94bfde4d19872c44cf65386e3"; // accounts[7]
-const pauserAccountPrivateKey =
- "829e924fdf021ba3dbbc4225edfece9aca04b929d6e75613329ca6f1d31c0bb4"; // accounts[9]
-const proxyOwnerAccountPrivateKey =
- "21d7212f3b4e5332fd465877b64926e3532653e2798a11255a46f533852dfe46"; // accounts[14]
-const upgraderAccountPrivateKey = proxyOwnerAccountPrivateKey;
-// var blacklisterAccountPrivateKey = "b0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773"; // accounts[9]
-
-const adminSlot =
- "0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b";
-const implSlot =
- "0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3";
-
-// set to true to enable verbose logging in the tests
-const debugLogging = false;
-
-function calculateFeeAmount(amount, fee, feeBase) {
- return Math.floor((fee / feeBase) * amount);
-}
-
-function checkMinterConfiguredEvent(
- configureMinterEvent,
- minter,
- minterAllowedAmount
-) {
- assert.strictEqual(configureMinterEvent.logs[0].event, "MinterConfigured");
- assert.strictEqual(configureMinterEvent.logs[0].args.minter, minter);
- assert.isTrue(
- configureMinterEvent.logs[0].args.minterAllowedAmount.eq(
- new BN(minterAllowedAmount)
- )
- );
-}
-
-function checkMinterRemovedEvent(minterRemovedEvent, minter) {
- assert.strictEqual(minterRemovedEvent.logs[0].event, "MinterRemoved");
- assert.strictEqual(minterRemovedEvent.logs[0].args.oldMinter, minter);
-}
-
-function checkTransferEvents(transferEvent, from, to, value) {
- assert.strictEqual(transferEvent.logs[0].event, "Transfer");
- assert.strictEqual(transferEvent.logs[0].args.from, from);
- assert.strictEqual(transferEvent.logs[0].args.to, to);
- assert.isTrue(transferEvent.logs[0].args.value.eq(new BN(value)));
-}
-
-function checkApprovalEvent(approvalEvent, approver, spender, value) {
- assert.strictEqual(approvalEvent.logs[0].event, "Approval");
- assert.strictEqual(approvalEvent.logs[0].args.owner, approver);
- assert.strictEqual(approvalEvent.logs[0].args.spender, spender);
- assert.isTrue(approvalEvent.logs[0].args.value.eq(new BN(value)));
-}
-
-function checkBurnEvent(burnEvent, burner, amount) {
- assert.strictEqual(burnEvent.logs[0].event, "Burn");
- assert.strictEqual(burnEvent.logs[0].args.burner, burner);
- assert.isTrue(burnEvent.logs[0].args.amount.eq(new BN(amount)));
-}
-
-function checkBlacklistEvent(blacklistEvent, account) {
- assert.strictEqual(blacklistEvent.logs[0].event, "Blacklisted");
- assert.strictEqual(blacklistEvent.logs[0].args._account, account);
-}
-
-function checkUnblacklistEvent(unblacklistEvent, account) {
- assert.strictEqual(unblacklistEvent.logs[0].event, "UnBlacklisted");
- assert.strictEqual(unblacklistEvent.logs[0].args._account, account);
-}
-
-function checkBlacklisterChangedEvent(blacklisterChangedEvent, blacklister) {
- assert.strictEqual(
- blacklisterChangedEvent.logs[0].event,
- "BlacklisterChanged"
- );
- assert.strictEqual(
- blacklisterChangedEvent.logs[0].args.newBlacklister,
- blacklister
- );
-}
-
-function checkPauserChangedEvent(pauserChangedEvent, pauser) {
- assert.strictEqual(pauserChangedEvent.logs[0].event, "PauserChanged");
- assert.strictEqual(pauserChangedEvent.logs[0].args.newAddress, pauser);
-}
-
-function checkTransferOwnershipEvent(
- transferOwnershipEvent,
- previousOwner,
- newOwner
-) {
- assert.strictEqual(
- transferOwnershipEvent.logs[0].event,
- "OwnershipTransferred"
- );
- assert.strictEqual(
- transferOwnershipEvent.logs[0].args.previousOwner,
- previousOwner
- );
- assert.strictEqual(transferOwnershipEvent.logs[0].args.newOwner, newOwner);
-}
-
-function checkUpdateMasterMinterEvent(updateMasterMinter, newMasterMinter) {
- assert.strictEqual(updateMasterMinter.logs[0].event, "MasterMinterChanged");
- assert.strictEqual(
- updateMasterMinter.logs[0].args.newMasterMinter,
- newMasterMinter
- );
-}
-
-function checkAdminChangedEvent(adminChangedEvent, previousAdmin, newAdmin) {
- assert.strictEqual(adminChangedEvent.logs[0].event, "AdminChanged");
- assert.strictEqual(
- adminChangedEvent.logs[0].args.previousAdmin,
- previousAdmin
- );
- assert.strictEqual(adminChangedEvent.logs[0].args.newAdmin, newAdmin);
-}
-
-function checkUpgradeEvent(upgradeEvent, implementation) {
- assert.strictEqual(upgradeEvent.logs[0].event, "Upgraded");
- assert.strictEqual(upgradeEvent.logs[0].args.implementation, implementation);
-}
-
-function checkPauseEvent(pause) {
- assert.strictEqual(pause.logs[0].event, "Pause");
-}
-
-function checkUnpauseEvent(unpause) {
- assert.strictEqual(unpause.logs[0].event, "Unpause");
-}
-
-function checkMintEvent(minting, to, amount, minter) {
- // Mint Event
- assert.strictEqual(minting.logs[0].event, "Mint");
- assert.strictEqual(minting.logs[0].args.minter, minter);
- assert.strictEqual(minting.logs[0].args.to, to);
- assert.isTrue(minting.logs[0].args.amount.eq(new BN(amount)));
-
- // Transfer from 0 Event
- assert.strictEqual(minting.logs[1].event, "Transfer");
- assert.strictEqual(minting.logs[1].args.from, nullAccount);
- assert.strictEqual(minting.logs[1].args.to, to);
- assert.isTrue(minting.logs[1].args.value.eq(new BN(amount)));
-}
-
-function checkBurnEvents(burning, amount, burner) {
- // Burn Event
- assert.strictEqual(burning.logs[0].event, "Burn");
- assert.strictEqual(burning.logs[0].args.burner, burner);
- assert.isTrue(burning.logs[0].args.amount.eq(new BN(amount)));
-
- // Transfer to 0 Event
- assert.strictEqual(burning.logs[1].event, "Transfer");
- assert.strictEqual(burning.logs[1].args.from, burner);
- assert.strictEqual(burning.logs[1].args.to, nullAccount);
- assert.isTrue(burning.logs[1].args.value.eq(new BN(amount)));
-}
-
-// Creates a state object, with default values replaced by
-// customVars where appropriate.
-function buildExpectedState(token, customVars) {
- // set each variable's default value
- const expectedState = {
- name,
- symbol,
- currency,
- decimals: new BN(decimals),
- masterMinter: masterMinterAccount,
- pauser: pauserAccount,
- blacklister: blacklisterAccount,
- tokenOwner: tokenOwnerAccount,
- proxiedTokenAddress: token.proxiedTokenAddress,
- initializedV1: trueInStorageFormat,
- upgrader: proxyOwnerAccount,
- balances: {
- arbitraryAccount: bigZero,
- masterMinterAccount: bigZero,
- minterAccount: bigZero,
- pauserAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- upgraderAccount: bigZero,
- },
- allowance: {
- arbitraryAccount: {
- masterMinterAccount: bigZero,
- minterAccount: bigZero,
- pauserAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- arbitraryAccount: bigZero,
- upgraderAccount: bigZero,
- },
- masterMinterAccount: {
- arbitraryAccount: bigZero,
- minterAccount: bigZero,
- pauserAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- masterMinterAccount: bigZero,
- upgraderAccount: bigZero,
- },
- minterAccount: {
- arbitraryAccount: bigZero,
- masterMinterAccount: bigZero,
- pauserAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- minterAccount: bigZero,
- upgraderAccount: bigZero,
- },
- pauserAccount: {
- arbitraryAccount: bigZero,
- masterMinterAccount: bigZero,
- minterAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- pauserAccount: bigZero,
- upgraderAccount: bigZero,
- },
- blacklisterAccount: {
- arbitraryAccount: bigZero,
- masterMinterAccount: bigZero,
- minterAccount: bigZero,
- pauserAccount: bigZero,
- tokenOwnerAccount: bigZero,
- blacklisterAccount: bigZero,
- upgraderAccount: bigZero,
- },
- tokenOwnerAccount: {
- arbitraryAccount: bigZero,
- masterMinterAccount: bigZero,
- minterAccount: bigZero,
- pauserAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- upgraderAccount: bigZero,
- },
- upgraderAccount: {
- arbitraryAccount: bigZero,
- masterMinterAccount: bigZero,
- minterAccount: bigZero,
- pauserAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- upgraderAccount: bigZero,
- },
- },
- totalSupply: bigZero,
- isAccountBlacklisted: {
- arbitraryAccount: false,
- masterMinterAccount: false,
- minterAccount: false,
- pauserAccount: false,
- blacklisterAccount: false,
- tokenOwnerAccount: false,
- upgraderAccount: false,
- },
- isAccountMinter: {
- arbitraryAccount: false,
- masterMinterAccount: false,
- minterAccount: false,
- pauserAccount: false,
- blacklisterAccount: false,
- tokenOwnerAccount: false,
- upgraderAccount: false,
- },
- minterAllowance: {
- arbitraryAccount: bigZero,
- masterMinterAccount: bigZero,
- minterAccount: bigZero,
- pauserAccount: bigZero,
- blacklisterAccount: bigZero,
- tokenOwnerAccount: bigZero,
- upgraderAccount: bigZero,
- },
- paused: false,
- };
-
- // for each item in customVars, set the item in expectedState
- let i;
- for (i = 0; i < customVars.length; ++i) {
- if (_.has(expectedState, customVars[i].variable)) {
- if (
- expectedState[customVars[i].variable] === customVars[i].expectedValue
- ) {
- throw new Error(
- "variable " +
- customVars[i].variable +
- " to test has same default state as expected state"
- );
- } else {
- _.set(
- expectedState,
- customVars[i].variable,
- customVars[i].expectedValue
- );
- }
- } else {
- // TODO: test the error
- throw new Error(
- "variable " + customVars[i].variable + " not found in expectedState"
- );
- }
- }
- return expectedState;
-}
-
-// BN-aware deep comparison
-function checkState(actual, expected, prefix) {
- for (const k in actual) {
- if (Object.prototype.hasOwnProperty.call(actual, k)) {
- const path = prefix ? prefix + "." + k : k;
- const actualV = actual[k];
- const expectedV = expected[k];
- if (typeof actualV === "object" && !BN.isBN(actualV)) {
- checkState(actualV, expectedV, path);
- } else {
- const msg = `expected ${path} to equal ${expectedV}, got ${actualV}`;
- if (BN.isBN(actualV)) {
- assert.isTrue(actualV.eq(expectedV), msg);
- } else {
- assert.strictEqual(actualV, expectedV, msg);
- }
- }
- }
- }
-}
-
-// For testing variance of specific variables from their default values.
-// customVars is an array of objects of the form,
-// {'variable': , 'expectedValue': }
-// to reference nested variables, name variable using dot syntax, e.g. 'allowance.arbitraryAccount.minterAccount'
-async function checkVariables(_tokens, _customVars) {
- // Iterate over array of tokens.
- const numTokens = _tokens.length;
- assert.strictEqual(numTokens, _customVars.length);
- let n;
- for (n = 0; n < numTokens; n++) {
- const token = _tokens[n];
- const customVars = _customVars[n];
- const expectedState = buildExpectedState(token, customVars);
- if (debugLogging) {
- console.log(
- util.inspect(expectedState, { showHidden: false, depth: null })
- );
- }
-
- const actualState = await getActualState(token);
- checkState(actualState, expectedState);
-
- // Check that sum of individual balances equals totalSupply
- const accounts = [
- arbitraryAccount,
- masterMinterAccount,
- minterAccount,
- pauserAccount,
- blacklisterAccount,
- tokenOwnerAccount,
- upgraderAccount,
- ];
- let balanceSum = bigZero;
- for (let i = 0; i < accounts.length; i++) {
- balanceSum = balanceSum.add(await token.balanceOf(accounts[i]));
- }
- const totalSupply = await token.totalSupply();
- assert.isTrue(balanceSum.eq(totalSupply));
- }
-}
-
-function hexToAddress(hex) {
- return web3.utils.toChecksumAddress(
- "0x" + hex.replace(/^0x/, "").padStart(40, "0")
- );
-}
-
-// build up actualState object to compare to expectedState object
-async function getActualState(token) {
- return Q.all([
- await token.name.call(),
- await token.symbol.call(),
- await token.currency.call(),
- await token.decimals.call(),
- await token.masterMinter.call(),
- await token.pauser.call(),
- await token.blacklister.call(),
- await token.owner.call(),
- await getImplementation(token),
- await getAdmin(token),
- await getInitializedV1(token),
- await token.balanceOf(arbitraryAccount),
- await token.balanceOf(masterMinterAccount),
- await token.balanceOf(minterAccount),
- await token.balanceOf(pauserAccount),
- await token.balanceOf(blacklisterAccount),
- await token.balanceOf(tokenOwnerAccount),
- await token.balanceOf(upgraderAccount),
- await token.allowance(arbitraryAccount, masterMinterAccount),
- await token.allowance(arbitraryAccount, minterAccount),
- await token.allowance(arbitraryAccount, pauserAccount),
- await token.allowance(arbitraryAccount, blacklisterAccount),
- await token.allowance(arbitraryAccount, tokenOwnerAccount),
- await token.allowance(arbitraryAccount, arbitraryAccount),
- await token.allowance(arbitraryAccount, upgraderAccount),
- await token.allowance(masterMinterAccount, arbitraryAccount),
- await token.allowance(masterMinterAccount, minterAccount),
- await token.allowance(masterMinterAccount, pauserAccount),
- await token.allowance(masterMinterAccount, blacklisterAccount),
- await token.allowance(masterMinterAccount, tokenOwnerAccount),
- await token.allowance(masterMinterAccount, masterMinterAccount),
- await token.allowance(masterMinterAccount, upgraderAccount),
- await token.allowance(minterAccount, arbitraryAccount),
- await token.allowance(minterAccount, masterMinterAccount),
- await token.allowance(minterAccount, pauserAccount),
- await token.allowance(minterAccount, blacklisterAccount),
- await token.allowance(minterAccount, tokenOwnerAccount),
- await token.allowance(minterAccount, minterAccount),
- await token.allowance(minterAccount, upgraderAccount),
- await token.allowance(pauserAccount, arbitraryAccount),
- await token.allowance(pauserAccount, masterMinterAccount),
- await token.allowance(pauserAccount, minterAccount),
- await token.allowance(pauserAccount, blacklisterAccount),
- await token.allowance(pauserAccount, tokenOwnerAccount),
- await token.allowance(pauserAccount, pauserAccount),
- await token.allowance(pauserAccount, upgraderAccount),
- await token.allowance(blacklisterAccount, arbitraryAccount),
- await token.allowance(blacklisterAccount, masterMinterAccount),
- await token.allowance(blacklisterAccount, minterAccount),
- await token.allowance(blacklisterAccount, pauserAccount),
- await token.allowance(blacklisterAccount, tokenOwnerAccount),
- await token.allowance(blacklisterAccount, blacklisterAccount),
- await token.allowance(blacklisterAccount, upgraderAccount),
- await token.allowance(tokenOwnerAccount, arbitraryAccount),
- await token.allowance(tokenOwnerAccount, masterMinterAccount),
- await token.allowance(tokenOwnerAccount, minterAccount),
- await token.allowance(tokenOwnerAccount, pauserAccount),
- await token.allowance(tokenOwnerAccount, blacklisterAccount),
- await token.allowance(tokenOwnerAccount, tokenOwnerAccount),
- await token.allowance(tokenOwnerAccount, upgraderAccount),
- await token.allowance(upgraderAccount, arbitraryAccount),
- await token.allowance(upgraderAccount, masterMinterAccount),
- await token.allowance(upgraderAccount, minterAccount),
- await token.allowance(upgraderAccount, pauserAccount),
- await token.allowance(upgraderAccount, blacklisterAccount),
- await token.allowance(upgraderAccount, tokenOwnerAccount),
- await token.allowance(upgraderAccount, upgraderAccount),
- await token.totalSupply(),
- await token.isBlacklisted(arbitraryAccount),
- await token.isBlacklisted(masterMinterAccount),
- await token.isBlacklisted(minterAccount),
- await token.isBlacklisted(pauserAccount),
- await token.isBlacklisted(blacklisterAccount),
- await token.isBlacklisted(tokenOwnerAccount),
- await token.isBlacklisted(upgraderAccount),
- await token.isMinter(arbitraryAccount),
- await token.isMinter(masterMinterAccount),
- await token.isMinter(minterAccount),
- await token.isMinter(pauserAccount),
- await token.isMinter(blacklisterAccount),
- await token.isMinter(tokenOwnerAccount),
- await token.isMinter(upgraderAccount),
- await token.minterAllowance(arbitraryAccount),
- await token.minterAllowance(masterMinterAccount),
- await token.minterAllowance(minterAccount),
- await token.minterAllowance(pauserAccount),
- await token.minterAllowance(blacklisterAccount),
- await token.minterAllowance(tokenOwnerAccount),
- await token.minterAllowance(upgraderAccount),
- await token.paused(),
- ]).spread(
- (
- name,
- symbol,
- currency,
- decimals,
- masterMinter,
- pauser,
- blacklister,
- tokenOwner,
- proxiedTokenAddress,
- upgrader,
- initializedV1,
- balancesA,
- balancesMM,
- balancesM,
- balancesP,
- balancesB,
- balancesRAC,
- balancesU,
- allowanceAtoMM,
- allowanceAtoM,
- allowanceAtoP,
- allowanceAtoB,
- allowanceAtoRAC,
- allowanceAtoA,
- allowanceAtoU,
- allowanceMMtoA,
- allowanceMMtoM,
- allowanceMMtoP,
- allowanceMMtoB,
- allowanceMMtoRAC,
- allowanceMMtoMM,
- allowanceMMtoU,
- allowanceMtoA,
- allowanceMtoMM,
- allowanceMtoP,
- allowanceMtoB,
- allowanceMtoRAC,
- allowanceMtoM,
- allowanceMtoU,
- allowancePtoA,
- allowancePtoMM,
- allowancePtoM,
- allowancePtoB,
- allowancePtoRAC,
- allowancePtoP,
- allowancePtoU,
- allowanceBtoA,
- allowanceBtoMM,
- allowanceBtoM,
- allowanceBtoP,
- allowanceBtoRAC,
- allowanceBtoB,
- allowanceBtoU,
- allowanceRACtoA,
- allowanceRACtoMM,
- allowanceRACtoM,
- allowanceRACtoP,
- allowanceRACtoB,
- allowanceRACtoRAC,
- allowanceRACtoU,
- allowanceUtoA,
- allowanceUtoMM,
- allowanceUtoM,
- allowanceUtoP,
- allowanceUtoB,
- allowanceUtoRAC,
- allowanceUtoU,
- totalSupply,
- isAccountBlacklistedA,
- isAccountBlacklistedMM,
- isAccountBlacklistedM,
- isAccountBlacklistedP,
- isAccountBlacklistedB,
- isAccountBlacklistedRAC,
- isAccountBlacklistedU,
- isAccountMinterA,
- isAccountMinterMM,
- isAccountMinterM,
- isAccountMinterP,
- isAccountMinterB,
- isAccountMinterRAC,
- isAccountMinterU,
- minterAllowanceA,
- minterAllowanceMM,
- minterAllowanceM,
- minterAllowanceP,
- minterAllowanceB,
- minterAllowanceRAC,
- minterAllowanceU,
- paused
- ) => {
- const actualState = {
- name,
- symbol,
- currency,
- decimals,
- masterMinter: hexToAddress(masterMinter),
- pauser: hexToAddress(pauser),
- blacklister: hexToAddress(blacklister),
- tokenOwner: hexToAddress(tokenOwner),
- proxiedTokenAddress: hexToAddress(proxiedTokenAddress),
- upgrader: hexToAddress(upgrader),
- initializedV1,
- balances: {
- arbitraryAccount: balancesA,
- masterMinterAccount: balancesMM,
- minterAccount: balancesM,
- pauserAccount: balancesP,
- blacklisterAccount: balancesB,
- tokenOwnerAccount: balancesRAC,
- upgraderAccount: balancesU,
- },
- allowance: {
- arbitraryAccount: {
- masterMinterAccount: allowanceAtoMM,
- minterAccount: allowanceAtoM,
- pauserAccount: allowanceAtoP,
- blacklisterAccount: allowanceAtoB,
- tokenOwnerAccount: allowanceAtoRAC,
- arbitraryAccount: allowanceAtoA,
- upgraderAccount: allowanceAtoU,
- },
- masterMinterAccount: {
- arbitraryAccount: allowanceMMtoA,
- minterAccount: allowanceMMtoM,
- pauserAccount: allowanceMMtoP,
- blacklisterAccount: allowanceMMtoB,
- tokenOwnerAccount: allowanceMMtoRAC,
- masterMinterAccount: allowanceMMtoMM,
- upgraderAccount: allowanceMMtoU,
- },
- minterAccount: {
- arbitraryAccount: allowanceMtoA,
- masterMinterAccount: allowanceMtoMM,
- pauserAccount: allowanceMtoP,
- blacklisterAccount: allowanceMtoB,
- tokenOwnerAccount: allowanceMtoRAC,
- minterAccount: allowanceMtoM,
- upgraderAccount: allowanceMtoU,
- },
- pauserAccount: {
- arbitraryAccount: allowancePtoA,
- masterMinterAccount: allowancePtoMM,
- minterAccount: allowancePtoM,
- blacklisterAccount: allowancePtoB,
- tokenOwnerAccount: allowancePtoRAC,
- pauserAccount: allowancePtoP,
- upgraderAccount: allowancePtoU,
- },
- blacklisterAccount: {
- arbitraryAccount: allowanceBtoA,
- masterMinterAccount: allowanceBtoMM,
- minterAccount: allowanceBtoM,
- pauserAccount: allowanceBtoP,
- tokenOwnerAccount: allowanceBtoRAC,
- blacklisterAccount: allowanceBtoB,
- upgraderAccount: allowanceBtoU,
- },
- tokenOwnerAccount: {
- arbitraryAccount: allowanceRACtoA,
- masterMinterAccount: allowanceRACtoMM,
- minterAccount: allowanceRACtoM,
- pauserAccount: allowanceRACtoP,
- blacklisterAccount: allowanceRACtoB,
- tokenOwnerAccount: allowanceRACtoRAC,
- upgraderAccount: allowanceRACtoU,
- },
- upgraderAccount: {
- arbitraryAccount: allowanceUtoA,
- masterMinterAccount: allowanceUtoMM,
- minterAccount: allowanceUtoM,
- pauserAccount: allowanceUtoP,
- blacklisterAccount: allowanceUtoB,
- tokenOwnerAccount: allowanceUtoRAC,
- upgraderAccount: allowanceUtoU,
- },
- },
- totalSupply,
- isAccountBlacklisted: {
- arbitraryAccount: isAccountBlacklistedA,
- masterMinterAccount: isAccountBlacklistedMM,
- minterAccount: isAccountBlacklistedM,
- pauserAccount: isAccountBlacklistedP,
- blacklisterAccount: isAccountBlacklistedB,
- tokenOwnerAccount: isAccountBlacklistedRAC,
- upgraderAccount: isAccountBlacklistedU,
- },
- isAccountMinter: {
- arbitraryAccount: isAccountMinterA,
- masterMinterAccount: isAccountMinterMM,
- minterAccount: isAccountMinterM,
- pauserAccount: isAccountMinterP,
- blacklisterAccount: isAccountMinterB,
- tokenOwnerAccount: isAccountMinterRAC,
- upgraderAccount: isAccountMinterU,
- },
- minterAllowance: {
- arbitraryAccount: minterAllowanceA,
- masterMinterAccount: minterAllowanceMM,
- minterAccount: minterAllowanceM,
- pauserAccount: minterAllowanceP,
- blacklisterAccount: minterAllowanceB,
- tokenOwnerAccount: minterAllowanceRAC,
- upgraderAccount: minterAllowanceU,
- },
- paused,
- };
- return actualState;
- }
- );
-}
-
-async function setMinter(token, minter, amount) {
- const update = await token.configureMinter(minter, amount, {
- from: masterMinterAccount,
- });
- assert.strictEqual(update.logs[0].event, "MinterConfigured");
- assert.strictEqual(update.logs[0].args.minter, minter);
- assert.isTrue(update.logs[0].args.minterAllowedAmount.eq(new BN(amount)));
- const minterAllowance = await token.minterAllowance(minter);
-
- assert.isTrue(minterAllowance.eq(new BN(amount)));
-}
-
-async function burn(token, amount, burner) {
- const burning = await token.burn(amount, { from: burner });
- checkBurnEvents(burning, amount, burner);
-}
-
-async function mint(token, to, amount, minter) {
- await setMinter(token, minter, amount);
- await mintRaw(token, to, amount, minter);
-}
-
-async function mintRaw(token, to, amount, minter) {
- const initialTotalSupply = await token.totalSupply();
- const initialMinterAllowance = await token.minterAllowance(minter);
- const minting = await token.mint(to, amount, { from: minter });
- checkMintEvent(minting, to, amount, minter);
-
- const totalSupply = await token.totalSupply();
- assert.isTrue(totalSupply.eq(initialTotalSupply.add(new BN(amount))));
- const minterAllowance = await token.minterAllowance(minter);
- assert.isTrue(initialMinterAllowance.sub(new BN(amount)).eq(minterAllowance));
-}
-
-async function blacklist(token, account) {
- const blacklist = await token.blacklist(account, {
- from: blacklisterAccount,
- });
- checkBlacklistEvent(blacklist, account);
-}
-
-async function unBlacklist(token, account) {
- const unblacklist = await token.unBlacklist(account, {
- from: blacklisterAccount,
- });
- checkUnblacklistEvent(unblacklist, account);
-}
-
-async function sampleTransfer(token, ownerAccount, arbitraryAccount, minter) {
- let allowed = await token.allowance.call(ownerAccount, arbitraryAccount);
- assert.isTrue(new BN(allowed).eqn(0));
- await mint(token, ownerAccount, 1900, minter);
-
- await token.approve(arbitraryAccount, 1500);
- allowed = await token.allowance.call(ownerAccount, arbitraryAccount);
- assert.isTrue(new BN(allowed).eqn(1500));
-
- const transfer = await token.transfer(arbitraryAccount, 1000, {
- from: ownerAccount,
- });
-
- checkTransferEvents(transfer, ownerAccount, arbitraryAccount, 1000);
-
- const balance0 = await token.balanceOf(ownerAccount);
- assert.isTrue(balance0.eqn(1900 - 1000));
- const balance3 = await token.balanceOf(arbitraryAccount);
- assert.isTrue(balance3.eqn(1000));
-}
-
-async function sampleTransferFrom(
- token,
- ownerAccount,
- arbitraryAccount,
- minter
-) {
- let allowed = await token.allowance.call(ownerAccount, arbitraryAccount); // TODO not this
- assert.isTrue(new BN(allowed).eqn(0));
- await mint(token, ownerAccount, 900, minter); // TODO maybe this
- await token.approve(arbitraryAccount, 634); // TODO not this
- allowed = await token.allowance.call(ownerAccount, arbitraryAccount); // TODO not this
- assert.isTrue(new BN(allowed).eqn(634));
-
- const transfer = await token.transferFrom(
- ownerAccount,
- arbitraryAccount,
- 534,
- {
- from: arbitraryAccount,
- }
- ); // TODO not this
-
- checkTransferEvents(transfer, ownerAccount, arbitraryAccount, 534);
-
- const balance0 = await token.balanceOf(ownerAccount);
- assert.isTrue(new BN(balance0).eqn(900 - 534));
- const balance3 = await token.balanceOf(arbitraryAccount);
- assert.isTrue(new BN(balance3).eqn(534));
-}
-
-async function approve(token, to, amount, from) {
- await token.approve(to, amount, { from });
-}
-
-async function redeem(token, account, amount) {
- const redeemResult = await token.redeem(amount, { from: account });
- assert.strictEqual(redeemResult.logs[0].event, "Redeem");
- assert.strictEqual(redeemResult.logs[0].args.redeemedAddress, account);
- assert.isTrue(redeemResult.logs[0].args.amount.eq(new BN(amount)));
-}
-
-function validateTransferEvent(transferEvent, from, to, value) {
- const eventResult = transferEvent.logs[0];
- assert.strictEqual(eventResult.event, "Transfer");
- assert.strictEqual(eventResult.args.from, from);
- assert.strictEqual(eventResult.args.to, to);
- assert.isTrue(eventResult.args.value.eq(new BN(value)));
-}
-
-async function initializeTokenWithProxy(rawToken) {
- return customInitializeTokenWithProxy(
- rawToken,
- masterMinterAccount,
- pauserAccount,
- blacklisterAccount,
- tokenOwnerAccount
- );
-}
-
-async function customInitializeTokenWithProxy(
- rawToken,
- _masterMinter,
- _pauser,
- _blacklister,
- _owner
-) {
- const proxy = await FiatTokenProxy.new(rawToken.address, {
- from: proxyOwnerAccount,
- });
- const proxiedToken = await FiatTokenV1.at(proxy.address);
- await proxiedToken.initialize(
- name,
- symbol,
- currency,
- decimals,
- _masterMinter,
- _pauser,
- _blacklister,
- _owner
- );
- proxiedToken.proxiedTokenAddress = rawToken.address;
- assert.strictEqual(proxiedToken.address, proxy.address);
- assert.notEqual(proxiedToken.address, rawToken.address);
- const tokenConfig = {
- proxy,
- token: proxiedToken,
- };
- return tokenConfig;
-}
-
-async function upgradeTo(proxy, upgradedToken, proxyUpgraderAccount) {
- if (proxyUpgraderAccount == null) {
- proxyUpgraderAccount = proxyOwnerAccount;
- }
- await proxy.upgradeTo(upgradedToken.address, { from: proxyUpgraderAccount });
- const proxiedToken = await FiatTokenV1.at(proxy.address);
- assert.strictEqual(proxiedToken.address, proxy.address);
- return {
- proxy,
- token: proxiedToken,
- };
-}
-
-async function expectRevert(contractPromise) {
- try {
- await contractPromise;
- } catch (error) {
- assert.isTrue(
- error.message.includes("revert"),
- "Expected error of type revert, got '" + error + "' instead"
- );
- return;
- }
- assert.fail("Expected error of type revert, but no error was received");
-}
-
-async function expectJump(contractPromise) {
- try {
- await contractPromise;
- assert.fail("Expected invalid opcode not received");
- } catch (error) {
- assert.isTrue(
- error.message.includes("invalid opcode"),
- `Expected "invalid opcode", got ${error} instead`
- );
- }
-}
-
-function encodeCall(name, args, values) {
- const methodId = abi.methodID(name, args).toString("hex");
- const params = abi.rawEncode(args, values).toString("hex");
- return "0x" + methodId + params;
-}
-
-async function getAdmin(proxy) {
- const adm = await web3.eth.getStorageAt(proxy.address, adminSlot);
- return web3.utils.toChecksumAddress("0x" + adm.slice(2).padStart(40, "0"));
-}
-
-async function getImplementation(proxy) {
- const impl = await web3.eth.getStorageAt(proxy.address, implSlot);
- return web3.utils.toChecksumAddress("0x" + impl.slice(2).padStart(40, "0"));
-}
-
-async function getInitializedV1(token) {
- const slot8Data = await web3.eth.getStorageAt(token.address, 8);
- let initialized;
-
- if (slot8Data === "0x0") {
- // validate proxy not yet initialized
- for (let i = 0; i <= 20; i++) {
- assert.strictEqual("0x0", await web3.eth.getStorageAt(token.address, i));
- }
- initialized = "0x00";
- } else {
- const slot8DataPadded = slot8Data.slice(2).padStart(42, "0");
- if (slot8DataPadded.length !== 42) {
- assert.fail("slot8Data unexpected size");
- }
- const masterMinterAddress = await token.masterMinter.call();
- assert.isTrue(
- slot8DataPadded.indexOf(masterMinterAddress.slice(2).toLowerCase()) === 2
- );
-
- initialized = "0x" + slot8DataPadded.slice(0, 2);
- }
- return initialized;
-}
-
-module.exports = {
- FiatTokenV1,
- FiatTokenProxy,
- UpgradedFiatToken,
- UpgradedFiatTokenNewFields,
- UpgradedFiatTokenNewFieldsNewLogic,
- name,
- symbol,
- currency,
- decimals,
- bigZero,
- bigHundred,
- debugLogging,
- calculateFeeAmount,
- checkTransferEvents,
- checkMinterConfiguredEvent,
- checkMintEvent,
- checkApprovalEvent,
- checkBurnEvents,
- checkBurnEvent,
- checkMinterRemovedEvent,
- checkBlacklistEvent,
- checkUnblacklistEvent,
- checkPauseEvent,
- checkUnpauseEvent,
- checkPauserChangedEvent,
- checkTransferOwnershipEvent,
- checkUpdateMasterMinterEvent,
- checkBlacklisterChangedEvent,
- checkUpgradeEvent,
- checkAdminChangedEvent,
- buildExpectedState,
- checkVariables,
- setMinter,
- mint,
- burn,
- mintRaw,
- blacklist,
- unBlacklist,
- sampleTransfer,
- sampleTransferFrom,
- approve,
- redeem,
- validateTransferEvent,
- initializeTokenWithProxy,
- customInitializeTokenWithProxy,
- upgradeTo,
- expectRevert,
- expectJump,
- encodeCall,
- getInitializedV1,
- nullAccount,
- deployerAccount,
- arbitraryAccount,
- tokenOwnerAccount,
- arbitraryAccount2,
- masterMinterAccount,
- minterAccount,
- pauserAccount,
- blacklisterAccount,
- proxyOwnerAccount,
- proxyOwnerAccountPrivateKey,
- upgraderAccount,
- getAdmin,
- arbitraryAccountPrivateKey,
- upgraderAccountPrivateKey,
- tokenOwnerPrivateKey,
- blacklisterAccountPrivateKey,
- arbitraryAccount2PrivateKey,
- masterMinterAccountPrivateKey,
- minterAccountPrivateKey,
- pauserAccountPrivateKey,
- deployerAccountPrivateKey,
-};
diff --git a/test/v1/abiHacking.test.js b/test/v1/abiHacking.test.js
index 14f02e8ad..99550f9ef 100644
--- a/test/v1/abiHacking.test.js
+++ b/test/v1/abiHacking.test.js
@@ -1,4 +1,21 @@
-const { Transaction } = require("ethereumjs-tx");
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const wrapTests = require("./helpers/wrapTests");
const {
expectRevert,
@@ -26,7 +43,7 @@ function mockStringAddressEncode(methodName, address) {
return functionSignature(methodName) + version + encodeAddress(address);
}
-function runTests(newToken, _accounts) {
+function runTests(newToken) {
let proxy, token;
beforeEach(async () => {
@@ -39,20 +56,12 @@ function runTests(newToken, _accounts) {
// sanity check for pausable
it("abi004 FiatToken pause() is public", async () => {
const badData = functionSignature("pause()");
- const tx = new Transaction({
- nonce: web3.utils.toHex(
- await web3.eth.getTransactionCount(pauserAccount)
- ),
- gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 100000,
- to: token.address,
- value: 0,
- data: badData,
- });
- const privateKey = Buffer.from(pauserAccountPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
-
+ const raw = await makeRawTransaction(
+ badData,
+ pauserAccount,
+ pauserAccountPrivateKey,
+ token.address
+ );
await sendRawTransaction(raw);
const customVars = [{ variable: "paused", expectedValue: true }];
await checkVariables([token], [customVars]);
@@ -60,77 +69,45 @@ function runTests(newToken, _accounts) {
it("abi040 Blacklistable constructor is not a function", async () => {
const badData = functionSignature("Blacklistable()");
- const tx = new Transaction({
- nonce: web3.utils.toHex(
- await web3.eth.getTransactionCount(pauserAccount)
- ),
- gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 100000,
- to: token.address,
- value: 0,
- data: badData,
- });
- const privateKey = Buffer.from(pauserAccountPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
-
+ const raw = await makeRawTransaction(
+ badData,
+ pauserAccount,
+ pauserAccountPrivateKey,
+ token.address
+ );
await expectRevert(sendRawTransaction(raw));
});
it("abi042 Ownable constructor is not a function", async () => {
const badData = functionSignature("Ownable()");
- const tx = new Transaction({
- nonce: web3.utils.toHex(
- await web3.eth.getTransactionCount(pauserAccount)
- ),
- gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 100000,
- to: token.address,
- value: 0,
- data: badData,
- });
- const privateKey = Buffer.from(pauserAccountPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
-
+ const raw = await makeRawTransaction(
+ badData,
+ pauserAccount,
+ pauserAccountPrivateKey,
+ token.address
+ );
await expectRevert(sendRawTransaction(raw));
});
it("abi005 Pausable constructor is not a function", async () => {
const badData = functionSignature("Pausable()");
- const tx = new Transaction({
- nonce: web3.utils.toHex(
- await web3.eth.getTransactionCount(pauserAccount)
- ),
- gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 100000,
- to: token.address,
- value: 0,
- data: badData,
- });
- const privateKey = Buffer.from(pauserAccountPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
-
+ const raw = await makeRawTransaction(
+ badData,
+ pauserAccount,
+ pauserAccountPrivateKey,
+ token.address
+ );
await expectRevert(sendRawTransaction(raw));
});
it("abi043 FiatTokenProxy constructor is not a function", async () => {
const badData = functionSignature("FiatTokenProxy()");
- const tx = new Transaction({
- nonce: web3.utils.toHex(
- await web3.eth.getTransactionCount(pauserAccount)
- ),
- gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 100000,
- to: token.address,
- value: 0,
- data: badData,
- });
- const privateKey = Buffer.from(pauserAccountPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
-
+ const raw = await makeRawTransaction(
+ badData,
+ pauserAccount,
+ pauserAccountPrivateKey,
+ token.address
+ );
await expectRevert(sendRawTransaction(raw));
});
@@ -230,39 +207,23 @@ function runTests(newToken, _accounts) {
it("abi041 FiatToken constructor is not a function", async () => {
const badData = functionSignature("FiatToken()");
- const tx = new Transaction({
- nonce: web3.utils.toHex(
- await web3.eth.getTransactionCount(pauserAccount)
- ),
- gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 100000,
- to: token.address,
- value: 0,
- data: badData,
- });
- const privateKey = Buffer.from(pauserAccountPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
-
+ const raw = await makeRawTransaction(
+ badData,
+ pauserAccount,
+ pauserAccountPrivateKey,
+ token.address
+ );
await expectRevert(sendRawTransaction(raw));
});
it("abi025 setOwner is internal", async () => {
const badData = msgData("setOwner(address)", pauserAccount);
- const tx = new Transaction({
- nonce: web3.utils.toHex(
- await web3.eth.getTransactionCount(tokenOwnerAccount)
- ),
- gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 100000,
- to: token.address,
- value: 0,
- data: badData,
- });
- const privateKey = Buffer.from(tokenOwnerPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
-
+ const raw = await makeRawTransaction(
+ badData,
+ tokenOwnerAccount,
+ tokenOwnerPrivateKey,
+ token.address
+ );
await expectRevert(sendRawTransaction(raw));
});
diff --git a/test/v1/events.test.js b/test/v1/events.test.js
index 4926d3690..9b7f22380 100644
--- a/test/v1/events.test.js
+++ b/test/v1/events.test.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const wrapTests = require("./helpers/wrapTests");
const {
FiatTokenV1,
@@ -25,14 +43,14 @@ const {
checkBlacklisterChangedEvent,
checkUpgradeEvent,
checkAdminChangedEvent,
- UpgradedFiatTokenNewFields,
+ deployUpgradedFiatTokenNewFields,
checkPauseEvent,
checkTransferEvents,
} = require("./helpers/tokenTest");
const amount = 100;
-function runTests(_newToken, _accounts) {
+function runTests(_newToken, version) {
let proxy, token;
beforeEach(async () => {
@@ -110,7 +128,7 @@ function runTests(_newToken, _accounts) {
});
it("et008 should check Upgraded event", async () => {
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
const initializeData = encodeCall(
"initV2",
["bool", "address", "uint256"],
diff --git a/test/v1/extendedPositive.test.js b/test/v1/extendedPositive.test.js
index 8603290f0..9a33d2b59 100644
--- a/test/v1/extendedPositive.test.js
+++ b/test/v1/extendedPositive.test.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const BN = require("bn.js");
const wrapTests = require("./helpers/wrapTests");
const {
@@ -10,13 +28,13 @@ const {
minterAccount,
pauserAccount,
initializeTokenWithProxy,
- UpgradedFiatToken,
+ deployUpgradedFiatToken,
upgradeTo,
} = require("./helpers/tokenTest");
const amount = 100;
-function runTests(newToken, _accounts) {
+function runTests(newToken, version) {
let proxy, token;
beforeEach(async () => {
@@ -112,7 +130,7 @@ function runTests(newToken, _accounts) {
});
it("ept008 should upgrade while paused", async () => {
- const newRawToken = await UpgradedFiatToken.new();
+ const newRawToken = await deployUpgradedFiatToken(version);
await token.pause({ from: pauserAccount });
const tokenConfig = await upgradeTo(proxy, newRawToken);
const newProxiedToken = tokenConfig.token;
@@ -248,7 +266,7 @@ function runTests(newToken, _accounts) {
it("ept022 should upgrade when msg.sender blacklisted", async () => {
await token.blacklist(upgraderAccount, { from: blacklisterAccount });
- const newRawToken = await UpgradedFiatToken.new();
+ const newRawToken = await deployUpgradedFiatToken(version);
const tokenConfig = await upgradeTo(proxy, newRawToken);
const newProxiedToken = tokenConfig.token;
@@ -260,7 +278,7 @@ function runTests(newToken, _accounts) {
});
it("ept023 should upgrade to blacklisted address", async () => {
- const newRawToken = await UpgradedFiatToken.new();
+ const newRawToken = await deployUpgradedFiatToken(version);
await token.blacklist(newRawToken.address, { from: blacklisterAccount });
const tokenConfig = await upgradeTo(proxy, newRawToken);
diff --git a/test/v1/helpers/abi.js b/test/v1/helpers/abi.js
index 402c65721..fb6761983 100644
--- a/test/v1/helpers/abi.js
+++ b/test/v1/helpers/abi.js
@@ -1,27 +1,46 @@
-const { Transaction } = require("ethereumjs-tx");
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-async function makeRawTransaction(data, from, hexPrivateKey, contractAddress) {
- const tx = new Transaction({
- nonce: web3.utils.toHex(await web3.eth.getTransactionCount(from)),
+async function makeRawTransaction(
+ data,
+ fromAddress,
+ fromAddressPrivateKey,
+ toAddress,
+ gasLimit = 1000000
+) {
+ const wallet = web3.eth.accounts.wallet.add({
+ privateKey: fromAddressPrivateKey,
+ address: fromAddress,
+ });
+ const { rawTransaction } = await wallet.signTransaction({
+ from: fromAddress,
+ to: toAddress,
+ gas: gasLimit,
gasPrice: web3.utils.toHex(web3.utils.toWei("20", "gwei")),
- gasLimit: 1000000,
- to: contractAddress,
value: 0,
data,
+ chainId: await web3.eth.getChainId(),
});
- const privateKey = Buffer.from(hexPrivateKey, "hex");
- tx.sign(privateKey);
- const raw = "0x" + tx.serialize().toString("hex");
- return raw;
+ return rawTransaction;
}
function sendRawTransaction(raw) {
- return new Promise((resolve, reject) => {
- web3.eth.sendSignedTransaction(raw, (err, transactionHash) => {
- if (err !== null) return reject(err);
- resolve(transactionHash);
- });
- });
+ return web3.eth.sendSignedTransaction(raw);
}
function functionSignature(methodName) {
diff --git a/test/v1/helpers/tokenTest.js b/test/v1/helpers/tokenTest.js
index b38aa9e37..3bad40967 100644
--- a/test/v1/helpers/tokenTest.js
+++ b/test/v1/helpers/tokenTest.js
@@ -1,14 +1,44 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const util = require("util");
const abi = require("ethereumjs-abi");
const _ = require("lodash");
const BN = require("bn.js");
+const BigNumber = require("bignumber.js");
const Q = require("q");
+const {
+ accounts,
+ accountPrivateKeys,
+ ZERO_ADDRESS,
+ ZERO_BYTES32,
+} = require("../../helpers/constants");
+const { linkLibraryToTokenContract } = require("../../helpers");
+
const FiatTokenV1 = artifacts.require("FiatTokenV1");
-const UpgradedFiatToken = artifacts.require("UpgradedFiatToken");
+const FiatTokenV2_2 = artifacts.require("FiatTokenV2_2");
const UpgradedFiatTokenNewFields = artifacts.require(
"UpgradedFiatTokenNewFieldsTest"
);
+const UpgradedFiatTokenV2_2NewFields = artifacts.require(
+ "UpgradedFiatTokenV2_2NewFieldsTest"
+);
const UpgradedFiatTokenNewFieldsNewLogic = artifacts.require(
"UpgradedFiatTokenNewFieldsNewLogicTest"
);
@@ -22,37 +52,33 @@ const trueInStorageFormat = "0x01";
const bigZero = new BN(0);
const bigHundred = new BN(100);
-const nullAccount = "0x0000000000000000000000000000000000000000";
-const deployerAccount = "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1"; // accounts[0]
-const arbitraryAccount = "0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0"; // accounts[1]
-const tokenOwnerAccount = "0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d"; // accounts[3]
-const blacklisterAccount = "0xd03ea8624C8C5987235048901fB614fDcA89b117"; // accounts[4]
-const arbitraryAccount2 = "0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC"; // accounts[5]
-const masterMinterAccount = "0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9"; // accounts[6]
-const minterAccount = "0x28a8746e75304c0780E011BEd21C72cD78cd535E"; // accounts[7]
-const pauserAccount = "0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E"; // accounts[8]
-
-const proxyOwnerAccount = "0x2F560290FEF1B3Ada194b6aA9c40aa71f8e95598"; // accounts[14]
+const {
+ deployerAccount,
+ arbitraryAccount,
+ tokenOwnerAccount,
+ blacklisterAccount,
+ arbitraryAccount2,
+ masterMinterAccount,
+ minterAccount,
+ pauserAccount,
+ proxyOwnerAccount,
+ rescuerAccount,
+ lostAndFoundAccount,
+} = accounts;
+const {
+ deployerAccount: deployerAccountPrivateKey,
+ arbitraryAccount: arbitraryAccountPrivateKey,
+ tokenOwnerAccount: tokenOwnerPrivateKey,
+ blacklisterAccount: blacklisterAccountPrivateKey,
+ arbitraryAccount2: arbitraryAccount2PrivateKey,
+ masterMinterAccount: masterMinterAccountPrivateKey,
+ minterAccount: minterAccountPrivateKey,
+ pauserAccount: pauserAccountPrivateKey,
+ proxyOwnerAccount: proxyOwnerAccountPrivateKey,
+ rescuerAccount: rescuerAccountPrivateKey,
+ lostAndFoundAccount: lostAndFoundAccountPrivateKey,
+} = accountPrivateKeys;
const upgraderAccount = proxyOwnerAccount;
-
-const deployerAccountPrivateKey =
- "4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"; // accounts[0]
-const arbitraryAccountPrivateKey =
- "6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1"; // accounts[1];
-const tokenOwnerPrivateKey =
- "646f1ce2fdad0e6deeeb5c7e8e5543bdde65e86029e2fd9fc169899c440a7913"; // accounts[3]
-const blacklisterAccountPrivateKey =
- "add53f9a7e588d003326d1cbf9e4a43c061aadd9bc938c843a79e7b4fd2ad743"; // accounts[4]
-const arbitraryAccount2PrivateKey =
- "395df67f0c2d2d9fe1ad08d1bc8b6627011959b79c53d7dd6a3536a33ab8a4fd"; // accounts[5]
-const masterMinterAccountPrivateKey =
- "e485d098507f54e7733a205420dfddbe58db035fa577fc294ebd14db90767a52"; // accounts[6]
-const minterAccountPrivateKey =
- "a453611d9419d0e56f499079478fd72c37b251a94bfde4d19872c44cf65386e3"; // accounts[7]
-const pauserAccountPrivateKey =
- "829e924fdf021ba3dbbc4225edfece9aca04b929d6e75613329ca6f1d31c0bb4"; // accounts[9]
-const proxyOwnerAccountPrivateKey =
- "21d7212f3b4e5332fd465877b64926e3532653e2798a11255a46f533852dfe46"; // accounts[14]
const upgraderAccountPrivateKey = proxyOwnerAccountPrivateKey;
const adminSlot =
@@ -187,7 +213,7 @@ function checkMintEvent(minting, to, amount, minter) {
// Transfer from 0 Event
assert.strictEqual(minting.logs[1].event, "Transfer");
- assert.strictEqual(minting.logs[1].args.from, nullAccount);
+ assert.strictEqual(minting.logs[1].args.from, ZERO_ADDRESS);
assert.strictEqual(minting.logs[1].args.to, to);
assert.isTrue(minting.logs[1].args.value.eq(new BN(amount)));
}
@@ -201,12 +227,14 @@ function checkBurnEvents(burning, amount, burner) {
// Transfer to 0 Event
assert.strictEqual(burning.logs[1].event, "Transfer");
assert.strictEqual(burning.logs[1].args.from, burner);
- assert.strictEqual(burning.logs[1].args.to, nullAccount);
+ assert.strictEqual(burning.logs[1].args.to, ZERO_ADDRESS);
assert.isTrue(burning.logs[1].args.value.eq(new BN(amount)));
}
-// Creates a state object, with default values replaced by
-// customVars where appropriate.
+/**
+ * Creates a state object, with default values replaced
+ * by customVars where appropriate.
+ */
function buildExpectedState(token, customVars) {
// set each variable's default value
const expectedState = {
@@ -221,7 +249,7 @@ function buildExpectedState(token, customVars) {
proxiedTokenAddress: token.proxiedTokenAddress,
initializedV1: trueInStorageFormat,
upgrader: proxyOwnerAccount,
- balances: {
+ balanceAndBlacklistStates: {
arbitraryAccount: bigZero,
masterMinterAccount: bigZero,
minterAccount: bigZero,
@@ -354,7 +382,9 @@ function buildExpectedState(token, customVars) {
return expectedState;
}
-// BN-aware deep comparison
+/**
+ * BN-aware deep comparison
+ */
function checkState(actual, expected, prefix) {
for (const k in actual) {
if (Object.prototype.hasOwnProperty.call(actual, k)) {
@@ -375,10 +405,15 @@ function checkState(actual, expected, prefix) {
}
}
-// For testing variance of specific variables from their default values.
-// customVars is an array of objects of the form,
-// {'variable': , 'expectedValue': }
-// to reference nested variables, name variable using dot syntax, e.g. 'allowance.arbitraryAccount.minterAccount'
+/**
+ * For testing variance of specific variables from their default values
+ *
+ * @param _tokens is an array of tokens
+ * @param _customVars is an array of objects of the form,
+ * {'variable': , 'expectedValue': }
+ *
+ * To reference nested variables, name variable using dot syntax, e.g. 'allowance.arbitraryAccount.minterAccount'
+ */
async function checkVariables(_tokens, _customVars) {
// Iterate over array of tokens.
const numTokens = _tokens.length;
@@ -422,7 +457,9 @@ function hexToAddress(hex) {
);
}
-// build up actualState object to compare to expectedState object
+/**
+ * Build up actualState object to compare to expectedState object
+ */
async function getActualState(token) {
return Q.all([
await token.name.call(),
@@ -620,7 +657,7 @@ async function getActualState(token) {
proxiedTokenAddress: hexToAddress(proxiedTokenAddress),
upgrader: hexToAddress(upgrader),
initializedV1,
- balances: {
+ balanceAndBlacklistStates: {
arbitraryAccount: balancesA,
masterMinterAccount: balancesMM,
minterAccount: balancesM,
@@ -912,18 +949,6 @@ async function expectRevert(contractPromise) {
assert.fail("Expected error of type revert, but no error was received");
}
-async function expectJump(contractPromise) {
- try {
- await contractPromise;
- assert.fail("Expected invalid opcode not received");
- } catch (error) {
- assert.isTrue(
- error.message.includes("invalid opcode"),
- `Expected "invalid opcode", got ${error} instead`
- );
- }
-}
-
function encodeCall(name, args, values) {
const methodId = abi.methodID(name, args).toString("hex");
const params = abi.rawEncode(args, values).toString("hex");
@@ -932,43 +957,106 @@ function encodeCall(name, args, values) {
async function getAdmin(proxy) {
const adm = await web3.eth.getStorageAt(proxy.address, adminSlot);
- return web3.utils.toChecksumAddress("0x" + adm.slice(2).padStart(40, "0"));
+ return web3.utils.toChecksumAddress("0x" + adm.slice(26));
}
async function getImplementation(proxy) {
const impl = await web3.eth.getStorageAt(proxy.address, implSlot);
- return web3.utils.toChecksumAddress("0x" + impl.slice(2).padStart(40, "0"));
+ return web3.utils.toChecksumAddress("0x" + impl.slice(26));
}
async function getInitializedV1(token) {
const slot8Data = await web3.eth.getStorageAt(token.address, 8);
let initialized;
- if (slot8Data === "0x0") {
+ if (slot8Data === ZERO_BYTES32) {
// validate proxy not yet initialized
for (let i = 0; i <= 20; i++) {
- assert.strictEqual("0x0", await web3.eth.getStorageAt(token.address, i));
+ assert.strictEqual(
+ ZERO_BYTES32,
+ await web3.eth.getStorageAt(token.address, i)
+ );
}
- initialized = "0x00";
+ initialized = ZERO_BYTES32;
} else {
- const slot8DataPadded = slot8Data.slice(2).padStart(42, "0");
- if (slot8DataPadded.length !== 42) {
+ if (slot8Data.length !== 66) {
assert.fail("slot8Data unexpected size");
}
- const masterMinterAddress = await token.masterMinter.call();
- assert.isTrue(
- slot8DataPadded.indexOf(masterMinterAddress.slice(2).toLowerCase()) === 2
+ // String layout
+ // 2 chars - 0x
+ // 22 zeroes chars
+ // 2 chars - initialized (bool)
+ // 40 chars - masterMinter (address)
+ initialized = "0x" + slot8Data.slice(24, 26);
+ const masterMinterAddress = web3.utils.toChecksumAddress(
+ "0x" + slot8Data.slice(26)
);
-
- initialized = "0x" + slot8DataPadded.slice(0, 2);
+ const expectedMasterMinterAddress = await token.masterMinter.call();
+ assert.strictEqual(masterMinterAddress, expectedMasterMinterAddress);
}
return initialized;
}
+async function deployUpgradedFiatToken(version) {
+ if (version < 2.2) {
+ return FiatTokenV1.new();
+ } else {
+ await linkLibraryToTokenContract(FiatTokenV2_2);
+ return FiatTokenV2_2.new();
+ }
+}
+
+async function deployUpgradedFiatTokenNewFields(version) {
+ if (version < 2.2) {
+ return UpgradedFiatTokenNewFields.new();
+ } else {
+ await linkLibraryToTokenContract(UpgradedFiatTokenV2_2NewFields);
+ return UpgradedFiatTokenV2_2NewFields.new();
+ }
+}
+
+/**
+ * Returns a new BN object
+ */
+function newBigNumber(value) {
+ const hex = new BigNumber(value).toString(16);
+ return new BN(hex, 16);
+}
+
+async function expectError(contractPromise, errorMsg) {
+ try {
+ await contractPromise;
+ assert.fail("Expected error " + errorMsg + ", but no error received");
+ } catch (error) {
+ const correctErrorMsgReceived = error.message.includes(errorMsg);
+ assert(
+ correctErrorMsgReceived,
+ `Expected ${errorMsg}, got ${error.message} instead`
+ );
+ }
+}
+
+/**
+ * Check to ensure correct format of the two inputs
+ *
+ * @param _contracts is an array of exactly two values: a FiatTokenV1 and a MintController
+ * @param _customVars is an array of exactly two values: the expected state of the FiatTokenV1
+ * and the expected state of the MintController
+ */
+async function checkMINTp0(_contracts, _customVars) {
+ assert.equal(_contracts.length, 2);
+ assert.equal(_customVars.length, 2);
+
+ // the first is a FiatTokenV1
+ await checkVariables([_contracts[0]], [_customVars[0]]);
+
+ // the second is a MintController
+ await _customVars[1].checkState(_contracts[1]);
+}
+
module.exports = {
FiatTokenV1,
FiatTokenProxy,
- UpgradedFiatToken,
UpgradedFiatTokenNewFields,
UpgradedFiatTokenNewFieldsNewLogic,
name,
@@ -978,6 +1066,8 @@ module.exports = {
bigZero,
bigHundred,
debugLogging,
+ newBigNumber,
+ checkMINTp0,
calculateFeeAmount,
checkTransferEvents,
checkMinterConfiguredEvent,
@@ -999,6 +1089,8 @@ module.exports = {
buildExpectedState,
checkVariables,
setMinter,
+ deployUpgradedFiatToken,
+ deployUpgradedFiatTokenNewFields,
mint,
burn,
mintRaw,
@@ -1013,10 +1105,10 @@ module.exports = {
customInitializeTokenWithProxy,
upgradeTo,
expectRevert,
- expectJump,
+ expectError,
encodeCall,
getInitializedV1,
- nullAccount,
+ nullAccount: ZERO_ADDRESS,
deployerAccount,
arbitraryAccount,
tokenOwnerAccount,
@@ -1024,6 +1116,8 @@ module.exports = {
masterMinterAccount,
minterAccount,
pauserAccount,
+ rescuerAccount,
+ lostAndFoundAccount,
blacklisterAccount,
proxyOwnerAccount,
proxyOwnerAccountPrivateKey,
@@ -1038,4 +1132,6 @@ module.exports = {
minterAccountPrivateKey,
pauserAccountPrivateKey,
deployerAccountPrivateKey,
+ rescuerAccountPrivateKey,
+ lostAndFoundAccountPrivateKey,
};
diff --git a/test/v1/helpers/wrapTests.js b/test/v1/helpers/wrapTests.js
index 34f2bdc14..b40977b90 100644
--- a/test/v1/helpers/wrapTests.js
+++ b/test/v1/helpers/wrapTests.js
@@ -1,34 +1,59 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const { linkLibraryToTokenContract } = require("../../helpers");
+
const FiatTokenV1 = artifacts.require("FiatTokenV1");
const FiatTokenV1_1 = artifacts.require("FiatTokenV1_1");
const FiatTokenV2 = artifacts.require("FiatTokenV2");
-
-// The following helpers make fresh original/upgraded tokens before each test.
-
-function newFiatTokenV1() {
- return FiatTokenV1.new();
-}
-
-function newFiatTokenV1_1() {
- return FiatTokenV1_1.new();
-}
-
-function newFiatTokenV2() {
- return FiatTokenV2.new();
-}
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+const FiatTokenV2_2 = artifacts.require("FiatTokenV2_2");
// Executes the run_tests_function using an original and
// an upgraded token. The test_suite_name is printed standard output.
function wrapTests(testSuiteName, runTestsFunction) {
- contract(`FiatTokenV1: ${testSuiteName}`, (accounts) => {
- runTestsFunction(newFiatTokenV1, accounts);
+ describe(`FiatTokenV1: ${testSuiteName}`, () => {
+ runTestsFunction(FiatTokenV1.new, 1);
+ });
+
+ describe(`FiatTokenV1_1: ${testSuiteName}`, () => {
+ runTestsFunction(FiatTokenV1_1.new, 1.1);
+ });
+
+ describe(`FiatTokenV2: ${testSuiteName}`, () => {
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2);
+ });
+ runTestsFunction(FiatTokenV2.new, 2);
});
- contract(`FiatTokenV1_1: ${testSuiteName}`, (accounts) => {
- runTestsFunction(newFiatTokenV1_1, accounts);
+ describe(`FiatTokenV2_1: ${testSuiteName}`, () => {
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2_1);
+ });
+ runTestsFunction(FiatTokenV2_1.new, 2.1);
});
- contract(`FiatTokenV2: ${testSuiteName}`, (accounts) => {
- runTestsFunction(newFiatTokenV2, accounts);
+ describe(`FiatTokenV2_2: ${testSuiteName}`, () => {
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2_2);
+ });
+ runTestsFunction(FiatTokenV2_2.new, 2.2);
});
}
diff --git a/test/v1/legacy.test.js b/test/v1/legacy.test.js
index a4373a93a..6a4fbe538 100644
--- a/test/v1/legacy.test.js
+++ b/test/v1/legacy.test.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const BN = require("bn.js");
const wrapTests = require("./helpers/wrapTests");
const {
@@ -26,17 +44,18 @@ const {
proxyOwnerAccount,
initializeTokenWithProxy,
upgradeTo,
- UpgradedFiatToken,
- FiatTokenV1,
getAdmin,
} = require("./helpers/tokenTest");
+const { HARDHAT_ACCOUNTS } = require("../helpers/constants");
// these tests are for reference and do not track side effects on all variables
-function runTests(_newToken, accounts) {
+function runTests(newToken, version) {
+ const accounts = HARDHAT_ACCOUNTS;
+
let proxy, token;
beforeEach(async () => {
- const rawToken = await FiatTokenV1.new();
+ const rawToken = await newToken();
const tokenConfig = await initializeTokenWithProxy(rawToken);
({ proxy, token } = tokenConfig);
assert.strictEqual(proxy.address, token.address);
@@ -428,24 +447,50 @@ function runTests(_newToken, accounts) {
assert.isTrue(new BN(balance).eqn(1900));
});
- it("should blacklist and make approve impossible", async () => {
- await mint(token, accounts[1], 1900, minterAccount);
- await blacklist(token, accounts[1]);
+ if (version < 2.2) {
+ it("should blacklist and make approve impossible", async () => {
+ await mint(token, accounts[1], 1900, minterAccount);
+ await blacklist(token, accounts[1]);
- await expectRevert(token.approve(accounts[2], 600, { from: accounts[1] }));
- const approval = await token.allowance(accounts[1], accounts[2]);
- assert.isTrue(new BN(approval).eqn(0));
- });
+ await expectRevert(
+ token.approve(accounts[2], 600, { from: accounts[1] })
+ );
+ const approval = await token.allowance(accounts[1], accounts[2]);
+ assert.isTrue(new BN(approval).eqn(0));
+ });
- it("should make giving approval to blacklisted account impossible", async () => {
- await mint(token, accounts[2], 1900, minterAccount);
- await blacklist(token, accounts[1]);
+ it("should make giving approval to blacklisted account impossible", async () => {
+ await mint(token, accounts[2], 1900, minterAccount);
+ await blacklist(token, accounts[1]);
- await expectRevert(token.approve(accounts[1], 600, { from: accounts[2] }));
+ await expectRevert(
+ token.approve(accounts[1], 600, { from: accounts[2] })
+ );
- const approval = await token.allowance(accounts[2], accounts[1]);
- assert.isTrue(new BN(approval).eqn(0));
- });
+ const approval = await token.allowance(accounts[2], accounts[1]);
+ assert.isTrue(new BN(approval).eqn(0));
+ });
+ } else {
+ // version >= 2.2
+
+ it("should approve when owner is blacklisted", async () => {
+ await mint(token, accounts[1], 1900, minterAccount);
+ await blacklist(token, accounts[1]);
+
+ await approve(token, accounts[1], 100, accounts[2]);
+ const allowance = await token.allowance(accounts[2], accounts[1]);
+ assert.isTrue(new BN(allowance).eqn(100));
+ });
+
+ it("should approve when spender is blacklisted", async () => {
+ await mint(token, accounts[2], 1900, minterAccount);
+ await blacklist(token, accounts[2]);
+
+ await approve(token, accounts[1], 100, accounts[2]);
+ const allowance = await token.allowance(accounts[2], accounts[1]);
+ assert.isTrue(new BN(allowance).eqn(100));
+ });
+ }
it("should blacklist then unblacklist to make a transfer possible", async () => {
await mint(token, accounts[2], 1900, minterAccount);
@@ -629,18 +674,17 @@ function runTests(_newToken, accounts) {
const initialBalance = await token.balanceOf(accounts[2]);
assert.isTrue(new BN(initialBalance).eqn(200));
- const newRawToken = await UpgradedFiatToken.new();
+ const newRawToken = await newToken();
const tokenConfig = await upgradeTo(proxy, newRawToken);
const newProxiedToken = tokenConfig.token;
- const newToken = newProxiedToken;
- const upgradedBalance = await newToken.balanceOf(accounts[2]);
+ const upgradedBalance = await newProxiedToken.balanceOf(accounts[2]);
assert.isTrue(new BN(upgradedBalance).eqn(200));
- await newToken.configureMinter(minterAccount, 500, {
+ await newProxiedToken.configureMinter(minterAccount, 500, {
from: masterMinterAccount,
});
- await newToken.mint(accounts[2], 200, { from: minterAccount });
- const balance = await newToken.balanceOf(accounts[2]);
+ await newProxiedToken.mint(accounts[2], 200, { from: minterAccount });
+ const balance = await newProxiedToken.balanceOf(accounts[2]);
assert.isTrue(new BN(balance).eqn(400));
});
@@ -699,18 +743,17 @@ function runTests(_newToken, accounts) {
const initialBalance = await token.balanceOf(accounts[2]);
assert.isTrue(new BN(initialBalance).eqn(200));
- const newRawToken = await UpgradedFiatToken.new();
+ const newRawToken = await newToken();
const tokenConfig = await upgradeTo(proxy, newRawToken, address1);
const newProxiedToken = tokenConfig.token;
- const newToken = newProxiedToken;
- const upgradedBalance = await newToken.balanceOf(accounts[2]);
+ const upgradedBalance = await newProxiedToken.balanceOf(accounts[2]);
assert.isTrue(new BN(upgradedBalance).eqn(200));
- await newToken.configureMinter(minterAccount, 500, {
+ await newProxiedToken.configureMinter(minterAccount, 500, {
from: masterMinterAccount,
});
- await newToken.mint(accounts[2], 200, { from: minterAccount });
- const balance = await newToken.balanceOf(accounts[2]);
+ await newProxiedToken.mint(accounts[2], 200, { from: minterAccount });
+ const balance = await newProxiedToken.balanceOf(accounts[2]);
assert.isTrue(new BN(balance).eqn(400));
});
diff --git a/test/v1/misc.test.js b/test/v1/misc.test.js
index db9f82ab1..31baff3a7 100644
--- a/test/v1/misc.test.js
+++ b/test/v1/misc.test.js
@@ -1,4 +1,31 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const BN = require("bn.js");
+const {
+ POW_2_255_HEX,
+ POW_2_255_BN,
+ POW_2_255_MINUS1_BN,
+ POW_2_255_MINUS1_HEX,
+ MAX_UINT256_HEX,
+ MAX_UINT256_BN,
+ ZERO_BYTES32,
+} = require("../helpers/constants");
const wrapTests = require("./helpers/wrapTests");
const {
checkVariables,
@@ -15,12 +42,9 @@ const {
FiatTokenProxy,
} = require("./helpers/tokenTest");
-const maxAmount =
- "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
-const maxAmountBN = new BN(maxAmount.slice(2), 16);
const amount = 100;
-function runTests(newToken, _accounts) {
+function runTests(newToken, version) {
let proxy, token;
beforeEach(async () => {
@@ -65,7 +89,7 @@ function runTests(newToken, _accounts) {
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -92,7 +116,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -121,7 +145,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -152,7 +176,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.minterAccount",
+ variable: "balanceAndBlacklistStates.minterAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -184,7 +208,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -258,7 +282,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount2),
},
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount1 + mintAmount2),
},
{
@@ -289,7 +313,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount1),
},
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount1 + mintAmount2),
},
{
@@ -362,7 +386,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -431,7 +455,7 @@ function runTests(newToken, _accounts) {
{ variable: "isAccountBlacklisted.minterAccount", expectedValue: true },
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount),
},
];
@@ -459,7 +483,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(mintAmount + mintAmount),
},
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount + mintAmount),
},
];
@@ -491,11 +515,11 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount2),
},
{
- variable: "balances.minterAccount",
+ variable: "balanceAndBlacklistStates.minterAccount",
expectedValue: new BN(mintAmount1),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount2),
},
{
@@ -519,11 +543,11 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount2),
},
{
- variable: "balances.minterAccount",
+ variable: "balanceAndBlacklistStates.minterAccount",
expectedValue: new BN(mintAmount1 - burnAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount2 - burnAmount),
},
{
@@ -635,7 +659,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -678,7 +702,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -719,37 +743,44 @@ function runTests(newToken, _accounts) {
});
const token = await FiatTokenV1.at(newProxy.address);
const initialized = await getInitializedV1(token);
- assert.strictEqual("0x00", initialized);
+ assert.strictEqual(ZERO_BYTES32, initialized);
});
it("ms047 configureMinter works on amount=2^256-1", async () => {
- await token.configureMinter(minterAccount, maxAmount, {
+ await token.configureMinter(minterAccount, MAX_UINT256_HEX, {
from: masterMinterAccount,
});
const customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
variable: "minterAllowance.minterAccount",
- expectedValue: maxAmountBN,
+ expectedValue: MAX_UINT256_BN,
},
];
await checkVariables([token], [customVars]);
});
- it("ms048 mint works on amount=2^256-1", async () => {
- await token.configureMinter(minterAccount, maxAmount, {
+ it(`ms048 mint works on amount=${
+ version < 2.2 ? "2^256-1" : "2^255-1"
+ }`, async () => {
+ const [amount, amountBN] =
+ version < 2.2
+ ? [MAX_UINT256_HEX, MAX_UINT256_BN]
+ : [POW_2_255_MINUS1_HEX, POW_2_255_MINUS1_BN];
+
+ await token.configureMinter(minterAccount, amount, {
from: masterMinterAccount,
});
let customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
variable: "minterAllowance.minterAccount",
- expectedValue: maxAmountBN,
+ expectedValue: amountBN,
},
];
await checkVariables([token], [customVars]);
- await token.mint(arbitraryAccount, maxAmount, { from: minterAccount });
+ await token.mint(arbitraryAccount, amount, { from: minterAccount });
customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
@@ -757,30 +788,70 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(0),
},
{
- variable: "balances.arbitraryAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: amountBN,
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ { variable: "totalSupply", expectedValue: amountBN },
];
await checkVariables([token], [customVars]);
});
- it("ms049 burn on works on amount=2^256-1", async () => {
- await token.configureMinter(minterAccount, maxAmount, {
+ if (version >= 2.2) {
+ it("ms048(b) mint does not work on amount=2^255", async () => {
+ await token.configureMinter(minterAccount, POW_2_255_HEX, {
+ from: masterMinterAccount,
+ });
+ let customVars = [
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: POW_2_255_BN,
+ },
+ ];
+ await checkVariables([token], [customVars]);
+
+ await expectRevert(
+ token.mint(arbitraryAccount, POW_2_255_HEX, { from: minterAccount })
+ );
+ customVars = [
+ { variable: "isAccountMinter.minterAccount", expectedValue: true },
+ {
+ variable: "minterAllowance.minterAccount",
+ expectedValue: POW_2_255_BN,
+ },
+ {
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: new BN(0),
+ },
+ { variable: "totalSupply", expectedValue: new BN(0) },
+ ];
+ await checkVariables([token], [customVars]);
+ });
+ }
+
+ it(`ms049 burn on works on amount=${
+ version < 2.2 ? "2^256-1" : "2^255-1"
+ }`, async () => {
+ const [amount, amountBN] =
+ version < 2.2
+ ? [MAX_UINT256_HEX, MAX_UINT256_BN]
+ : [POW_2_255_MINUS1_HEX, POW_2_255_MINUS1_BN];
+
+ await token.configureMinter(minterAccount, amount, {
from: masterMinterAccount,
});
- await token.mint(minterAccount, maxAmount, { from: minterAccount });
+ await token.mint(minterAccount, amount, { from: minterAccount });
let customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.minterAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.minterAccount",
+ expectedValue: amountBN,
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ { variable: "totalSupply", expectedValue: amountBN },
];
await checkVariables([token], [customVars]);
- await token.burn(maxAmount, { from: minterAccount });
+ await token.burn(amount, { from: minterAccount });
customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
];
@@ -788,93 +859,130 @@ function runTests(newToken, _accounts) {
});
it("ms050 approve works on amount=2^256-1", async () => {
- await token.configureMinter(minterAccount, maxAmount, {
+ const [mintAmount, mintAmountBN] =
+ version < 2.2
+ ? [MAX_UINT256_HEX, MAX_UINT256_BN]
+ : [POW_2_255_MINUS1_HEX, POW_2_255_MINUS1_BN];
+
+ await token.configureMinter(minterAccount, mintAmount, {
from: masterMinterAccount,
});
- await token.mint(arbitraryAccount, maxAmount, { from: minterAccount });
+ await token.mint(arbitraryAccount, mintAmount, {
+ from: minterAccount,
+ });
let customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.arbitraryAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: mintAmountBN,
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
+ expectedValue: new BN(0),
+ },
+ { variable: "totalSupply", expectedValue: mintAmountBN },
];
await checkVariables([token], [customVars]);
- await token.approve(pauserAccount, maxAmount, { from: arbitraryAccount });
+ await token.approve(pauserAccount, MAX_UINT256_HEX, {
+ from: arbitraryAccount,
+ });
customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.arbitraryAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: mintAmountBN,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
+ expectedValue: new BN(0),
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ { variable: "totalSupply", expectedValue: mintAmountBN },
{
variable: "allowance.arbitraryAccount.pauserAccount",
- expectedValue: maxAmountBN,
+ expectedValue: MAX_UINT256_BN,
},
];
await checkVariables([token], [customVars]);
});
- it("ms051 transfer works on amount=2^256-1", async () => {
- await token.configureMinter(minterAccount, maxAmount, {
+ it(`ms051 transfer works on amount=${
+ version < 2.2 ? "2^256-1" : "2^255-1"
+ }`, async () => {
+ const [amount, amountBN] =
+ version < 2.2
+ ? [MAX_UINT256_HEX, MAX_UINT256_BN]
+ : [POW_2_255_MINUS1_HEX, POW_2_255_MINUS1_BN];
+
+ await token.configureMinter(minterAccount, amount, {
from: masterMinterAccount,
});
- await token.mint(arbitraryAccount, maxAmount, { from: minterAccount });
+ await token.mint(arbitraryAccount, amount, { from: minterAccount });
let customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.arbitraryAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: amountBN,
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ { variable: "totalSupply", expectedValue: amountBN },
];
await checkVariables([token], [customVars]);
- await token.transfer(pauserAccount, maxAmount, { from: arbitraryAccount });
+ await token.transfer(pauserAccount, amount, {
+ from: arbitraryAccount,
+ });
customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.pauserAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.pauserAccount",
+ expectedValue: amountBN,
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ { variable: "totalSupply", expectedValue: amountBN },
];
await checkVariables([token], [customVars]);
});
- it("ms052 transferFrom works on amount=2^256-1", async () => {
- await token.configureMinter(minterAccount, maxAmount, {
+ it(`ms052 transferFrom works on amount=${
+ version < 2.2 ? "2^256-1" : "2^255-1"
+ }`, async () => {
+ const [amount, amountBN] =
+ version < 2.2
+ ? [MAX_UINT256_HEX, MAX_UINT256_BN]
+ : [POW_2_255_MINUS1_HEX, POW_2_255_MINUS1_BN];
+
+ await token.configureMinter(minterAccount, amount, {
from: masterMinterAccount,
});
- await token.mint(arbitraryAccount, maxAmount, { from: minterAccount });
- await token.approve(pauserAccount, maxAmount, { from: arbitraryAccount });
+ await token.mint(arbitraryAccount, amount, {
+ from: minterAccount,
+ });
+ await token.approve(pauserAccount, amount, {
+ from: arbitraryAccount,
+ });
let customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.arbitraryAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: amountBN,
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ { variable: "totalSupply", expectedValue: amountBN },
{
variable: "allowance.arbitraryAccount.pauserAccount",
- expectedValue: maxAmountBN,
+ expectedValue: amountBN,
},
];
await checkVariables([token], [customVars]);
- await token.transferFrom(arbitraryAccount, pauserAccount, maxAmount, {
+ await token.transferFrom(arbitraryAccount, pauserAccount, amount, {
from: pauserAccount,
});
customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.pauserAccount",
- expectedValue: maxAmountBN,
+ variable: "balanceAndBlacklistStates.pauserAccount",
+ expectedValue: amountBN,
},
- { variable: "totalSupply", expectedValue: maxAmountBN },
+ { variable: "totalSupply", expectedValue: amountBN },
];
await checkVariables([token], [customVars]);
});
diff --git a/test/v1/negative.test.js b/test/v1/negative.test.js
index d443791a2..28ebc6ed5 100644
--- a/test/v1/negative.test.js
+++ b/test/v1/negative.test.js
@@ -1,8 +1,26 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const wrapTests = require("./helpers/wrapTests");
const BN = require("bn.js");
+const { expectRevert } = require("../helpers");
const {
checkVariables,
- expectRevert,
nullAccount,
arbitraryAccount,
arbitraryAccount2,
@@ -14,12 +32,11 @@ const {
initializeTokenWithProxy,
customInitializeTokenWithProxy,
upgradeTo,
- UpgradedFiatToken,
} = require("./helpers/tokenTest");
const amount = 100;
-function runTests(newToken, _accounts) {
+function runTests(newToken, version) {
let proxy, token;
beforeEach(async () => {
@@ -135,30 +152,32 @@ function runTests(newToken, _accounts) {
// Approve
- it("nt008 should fail to approve when spender is blacklisted", async () => {
- await token.blacklist(minterAccount, { from: blacklisterAccount });
- const customVars = [
- { variable: "isAccountBlacklisted.minterAccount", expectedValue: true },
- ];
- await expectRevert(
- token.approve(minterAccount, 100, { from: arbitraryAccount })
- );
- await checkVariables([token], [customVars]);
- });
+ if (version < 2.2) {
+ it("nt008 should fail to approve when spender is blacklisted", async () => {
+ await token.blacklist(minterAccount, { from: blacklisterAccount });
+ const customVars = [
+ { variable: "isAccountBlacklisted.minterAccount", expectedValue: true },
+ ];
+ await expectRevert(
+ token.approve(minterAccount, 100, { from: arbitraryAccount })
+ );
+ await checkVariables([token], [customVars]);
+ });
- it("nt009 should fail to approve when msg.sender is blacklisted", async () => {
- await token.blacklist(arbitraryAccount, { from: blacklisterAccount });
- const customVars = [
- {
- variable: "isAccountBlacklisted.arbitraryAccount",
- expectedValue: true,
- },
- ];
- await expectRevert(
- token.approve(minterAccount, 100, { from: arbitraryAccount })
- );
- await checkVariables([token], [customVars]);
- });
+ it("nt009 should fail to approve when msg.sender is blacklisted", async () => {
+ await token.blacklist(arbitraryAccount, { from: blacklisterAccount });
+ const customVars = [
+ {
+ variable: "isAccountBlacklisted.arbitraryAccount",
+ expectedValue: true,
+ },
+ ];
+ await expectRevert(
+ token.approve(minterAccount, 100, { from: arbitraryAccount })
+ );
+ await checkVariables([token], [customVars]);
+ });
+ }
it("nt010 should fail to approve when contract is paused", async () => {
await token.pause({ from: pauserAccount });
@@ -193,7 +212,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -232,7 +251,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -272,7 +291,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.blacklisterAccount",
+ variable: "balanceAndBlacklistStates.blacklisterAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -316,7 +335,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.tokenOwnerAccount",
+ variable: "balanceAndBlacklistStates.tokenOwnerAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -360,7 +379,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -403,7 +422,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -443,7 +462,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -484,7 +503,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -516,7 +535,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -549,7 +568,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.tokenOwnerAccount",
+ variable: "balanceAndBlacklistStates.tokenOwnerAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -586,7 +605,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -623,7 +642,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - 50),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(50),
},
{ variable: "totalSupply", expectedValue: new BN(50) },
@@ -704,12 +723,15 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(0),
},
{
- variable: "balances.minterAccount",
+ variable: "balanceAndBlacklistStates.minterAccount",
expectedValue: new BN(amount),
},
{ variable: "totalSupply", expectedValue: new BN(amount) },
];
- await expectRevert(token.burn(-1, { from: minterAccount }));
+ await expectRevert(
+ token.burn(-1, { from: minterAccount }),
+ "value out-of-bounds"
+ );
await checkVariables([token], [customVars]);
});
@@ -734,7 +756,10 @@ function runTests(newToken, _accounts) {
variable: "minterAllowance.minterAccount",
expectedValue: new BN(amount - 50),
},
- { variable: "balances.minterAccount", expectedValue: new BN(50) },
+ {
+ variable: "balanceAndBlacklistStates.minterAccount",
+ expectedValue: new BN(50),
+ },
{ variable: "totalSupply", expectedValue: new BN(50) },
{ variable: "isAccountBlacklisted.minterAccount", expectedValue: true },
];
@@ -763,7 +788,10 @@ function runTests(newToken, _accounts) {
variable: "minterAllowance.minterAccount",
expectedValue: new BN(amount - 50),
},
- { variable: "balances.minterAccount", expectedValue: new BN(50) },
+ {
+ variable: "balanceAndBlacklistStates.minterAccount",
+ expectedValue: new BN(50),
+ },
{ variable: "totalSupply", expectedValue: new BN(50) },
{ variable: "paused", expectedValue: true },
];
@@ -791,7 +819,10 @@ function runTests(newToken, _accounts) {
variable: "minterAllowance.minterAccount",
expectedValue: new BN(amount - 50),
},
- { variable: "balances.minterAccount", expectedValue: new BN(50) },
+ {
+ variable: "balanceAndBlacklistStates.minterAccount",
+ expectedValue: new BN(50),
+ },
{ variable: "totalSupply", expectedValue: new BN(50) },
];
await expectRevert(token.burn(50, { from: arbitraryAccount }));
@@ -818,7 +849,10 @@ function runTests(newToken, _accounts) {
variable: "minterAllowance.minterAccount",
expectedValue: new BN(amount - 50),
},
- { variable: "balances.minterAccount", expectedValue: new BN(50) },
+ {
+ variable: "balanceAndBlacklistStates.minterAccount",
+ expectedValue: new BN(50),
+ },
{ variable: "totalSupply", expectedValue: new BN(50) },
];
await checkVariables([token], [customVars]);
@@ -830,7 +864,10 @@ function runTests(newToken, _accounts) {
variable: "minterAllowance.minterAccount",
expectedValue: new BN(0),
},
- { variable: "balances.minterAccount", expectedValue: new BN(50) },
+ {
+ variable: "balanceAndBlacklistStates.minterAccount",
+ expectedValue: new BN(50),
+ },
{ variable: "totalSupply", expectedValue: new BN(50) },
];
await expectRevert(token.burn(50, { from: minterAccount }));
@@ -901,10 +938,9 @@ function runTests(newToken, _accounts) {
it("nt054 should fail to transferOwnership when sender is not owner", async () => {
// Create upgraded token
- const newRawToken = await UpgradedFiatToken.new();
+ const newRawToken = await newToken();
const tokenConfig = await upgradeTo(proxy, newRawToken);
const newProxiedToken = tokenConfig.token;
- const newToken = newProxiedToken;
const newTokenResult = [
{ variable: "proxiedTokenAddress", expectedValue: newRawToken.address },
@@ -912,9 +948,11 @@ function runTests(newToken, _accounts) {
// expectRevert on transferOwnership with wrong sender
await expectRevert(
- newToken.transferOwnership(arbitraryAccount, { from: arbitraryAccount2 })
+ newProxiedToken.transferOwnership(arbitraryAccount, {
+ from: arbitraryAccount2,
+ })
);
- await checkVariables([newToken], [newTokenResult]);
+ await checkVariables([newProxiedToken], [newTokenResult]);
});
it("nt055 should fail to mint when amount = 0", async () => {
@@ -942,7 +980,7 @@ function runTests(newToken, _accounts) {
const customVars = [
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
{
- variable: "balances.minterAccount",
+ variable: "balanceAndBlacklistStates.minterAccount",
expectedValue: new BN(amount),
},
{ variable: "totalSupply", expectedValue: new BN(amount) },
diff --git a/test/v1/positive.test.js b/test/v1/positive.test.js
index 6e239b6ca..61a326c2b 100644
--- a/test/v1/positive.test.js
+++ b/test/v1/positive.test.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const BN = require("bn.js");
const wrapTests = require("./helpers/wrapTests");
const {
@@ -14,7 +32,7 @@ const {
const amount = 100;
-function runTests(newToken, _accounts) {
+function runTests(newToken) {
let proxy, token;
beforeEach(async () => {
@@ -125,7 +143,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -148,7 +166,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(0),
},
{
- variable: "balances.minterAccount",
+ variable: "balanceAndBlacklistStates.minterAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -163,7 +181,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(0),
},
{
- variable: "balances.minterAccount",
+ variable: "balanceAndBlacklistStates.minterAccount",
expectedValue: new BN(mintAmount - burnAmount),
},
{
@@ -190,7 +208,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -200,7 +218,7 @@ function runTests(newToken, _accounts) {
await token.removeMinter(minterAccount, { from: masterMinterAccount });
customVars = [
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -233,7 +251,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -247,9 +265,12 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -280,7 +301,7 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{
- variable: "balances.arbitraryAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -299,9 +320,12 @@ function runTests(newToken, _accounts) {
variable: "minterAllowance.minterAccount",
expectedValue: new BN(amount - mintAmount),
},
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
diff --git a/test/v1/proxyNegative.test.js b/test/v1/proxyNegative.test.js
index 65363b76b..f6ade4e38 100644
--- a/test/v1/proxyNegative.test.js
+++ b/test/v1/proxyNegative.test.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const BN = require("bn.js");
const wrapTests = require("./helpers/wrapTests");
const {
@@ -19,13 +37,12 @@ const {
initializeTokenWithProxy,
encodeCall,
FiatTokenV1,
- UpgradedFiatToken,
- UpgradedFiatTokenNewFields,
+ deployUpgradedFiatTokenNewFields,
} = require("./helpers/tokenTest");
const amount = 100;
-function runTests(newToken, _accounts) {
+function runTests(newToken, version) {
let rawToken, proxy, token;
beforeEach(async () => {
@@ -119,7 +136,7 @@ function runTests(newToken, _accounts) {
});
it("nut009 should fail to call upgradeTo with non-adminAccount", async () => {
- const upgradedToken = await UpgradedFiatToken.new();
+ const upgradedToken = await newToken();
await expectRevert(
proxy.upgradeTo(upgradedToken.address, { from: masterMinterAccount })
);
@@ -134,7 +151,7 @@ function runTests(newToken, _accounts) {
});
it("nut010 should fail to call updateToAndCall with non-adminAccount", async () => {
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
const initializeData = encodeCall(
"initialize",
["bool", "address", "uint256"],
@@ -164,7 +181,7 @@ function runTests(newToken, _accounts) {
await token.mint(arbitraryAccount, mintAmount, { from: minterAccount });
await token.transfer(pauserAccount, mintAmount, { from: arbitraryAccount });
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
const data = encodeCall(
"initialize",
[
@@ -206,9 +223,12 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
diff --git a/test/v1/proxyPositive.test.js b/test/v1/proxyPositive.test.js
index 9b128bb73..0a2f1d241 100644
--- a/test/v1/proxyPositive.test.js
+++ b/test/v1/proxyPositive.test.js
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
const wrapTests = require("./helpers/wrapTests");
const BN = require("bn.js");
const {
@@ -21,16 +39,16 @@ const {
encodeCall,
validateTransferEvent,
FiatTokenProxy,
- UpgradedFiatToken,
UpgradedFiatTokenNewFields,
UpgradedFiatTokenNewFieldsNewLogic,
getAdmin,
+ deployUpgradedFiatTokenNewFields,
} = require("./helpers/tokenTest");
const { makeRawTransaction, sendRawTransaction } = require("./helpers/abi");
const amount = 100;
-function runTests(newToken, _accounts) {
+function runTests(newToken, version) {
let rawToken, proxy, token;
beforeEach(async () => {
@@ -49,13 +67,13 @@ function runTests(newToken, _accounts) {
await token.mint(arbitraryAccount, mintAmount, { from: minterAccount });
await token.transfer(pauserAccount, mintAmount, { from: arbitraryAccount });
- const upgradedToken = await UpgradedFiatToken.new();
+ const upgradedToken = await newToken();
const tokenConfig = await upgradeTo(
proxy,
upgradedToken,
proxyOwnerAccount
);
- const newToken = tokenConfig.token;
+ const proxiedToken = tokenConfig.token;
const customVars = [
{
@@ -63,12 +81,18 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
- { variable: "balances.pauserAccount", expectedValue: new BN(mintAmount) },
+ {
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
+ expectedValue: new BN(mintAmount),
+ },
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
{ variable: "proxiedTokenAddress", expectedValue: upgradedToken.address },
];
- await checkVariables([newToken], [customVars]);
+ await checkVariables([proxiedToken], [customVars]);
});
it("upt002 should upgradeToandCall to contract with new data fields set on initVX and ensure new fields are correct and old data is preserved", async () => {
@@ -80,7 +104,7 @@ function runTests(newToken, _accounts) {
await token.mint(arbitraryAccount, mintAmount, { from: minterAccount });
await token.transfer(pauserAccount, mintAmount, { from: arbitraryAccount });
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
const initializeData = encodeCall(
"initV2",
["bool", "address", "uint256"],
@@ -103,8 +127,14 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
- { variable: "balances.pauserAccount", expectedValue: new BN(mintAmount) },
+ {
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
+ expectedValue: new BN(mintAmount),
+ },
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
{ variable: "proxiedTokenAddress", expectedValue: upgradedToken.address },
];
@@ -148,9 +178,12 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -160,7 +193,7 @@ function runTests(newToken, _accounts) {
});
it("upt008 should deploy upgraded version of contract with new data fields and without previous deployment and ensure new fields correct", async () => {
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
const newProxy = await FiatTokenProxy.new(upgradedToken.address, {
from: proxyOwnerAccount,
});
@@ -289,15 +322,15 @@ function runTests(newToken, _accounts) {
await token.mint(arbitraryAccount, mintAmount + 1, { from: minterAccount });
await token.transfer(pauserAccount, mintAmount, { from: arbitraryAccount });
- const upgradedToken = await UpgradedFiatToken.new();
+ const upgradedToken = await newToken();
const tokenConfig = await upgradeTo(
proxy,
upgradedToken,
proxyOwnerAccount
);
- const newToken = tokenConfig.token;
+ const proxiedToken = tokenConfig.token;
- const transfer = await newToken.transfer(pauserAccount, 1, {
+ const transfer = await proxiedToken.transfer(pauserAccount, 1, {
from: arbitraryAccount,
});
validateTransferEvent(transfer, arbitraryAccount, pauserAccount, new BN(1));
@@ -308,39 +341,42 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount - 1),
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount + 1),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount + 1) },
{ variable: "proxiedTokenAddress", expectedValue: upgradedToken.address },
];
- await checkVariables([newToken], [customVars]);
+ await checkVariables([proxiedToken], [customVars]);
});
it("upt006 should upgrade while paused and upgraded contract should be paused as a result; then unpause should unpause contract", async () => {
await token.pause({ from: pauserAccount });
- const upgradedToken = await UpgradedFiatToken.new();
+ const upgradedToken = await newToken();
const tokenConfig = await upgradeTo(
proxy,
upgradedToken,
proxyOwnerAccount
);
- const newToken = tokenConfig.token;
+ const proxiedToken = tokenConfig.token;
const customVars = [
{ variable: "paused", expectedValue: true },
{ variable: "proxiedTokenAddress", expectedValue: upgradedToken.address },
];
- await checkVariables([newToken], [customVars]);
+ await checkVariables([proxiedToken], [customVars]);
- await newToken.unpause({ from: pauserAccount });
+ await proxiedToken.unpause({ from: pauserAccount });
const customVars2 = [
{ variable: "proxiedTokenAddress", expectedValue: upgradedToken.address },
];
- await checkVariables([newToken], [customVars2]);
+ await checkVariables([proxiedToken], [customVars2]);
});
it("upt007 should upgrade contract to original address", async () => {
@@ -362,9 +398,12 @@ function runTests(newToken, _accounts) {
expectedValue: new BN(amount - mintAmount),
},
{ variable: "isAccountMinter.minterAccount", expectedValue: true },
- { variable: "balances.arbitraryAccount", expectedValue: bigZero },
{
- variable: "balances.pauserAccount",
+ variable: "balanceAndBlacklistStates.arbitraryAccount",
+ expectedValue: bigZero,
+ },
+ {
+ variable: "balanceAndBlacklistStates.pauserAccount",
expectedValue: new BN(mintAmount),
},
{ variable: "totalSupply", expectedValue: new BN(mintAmount) },
@@ -382,7 +421,7 @@ function runTests(newToken, _accounts) {
it("upt011 should upgradeToAndCall while paused and upgraded contract should be paused as a result", async () => {
await token.pause({ from: pauserAccount });
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
const initializeData = encodeCall(
"initV2",
["bool", "address", "uint256"],
@@ -405,7 +444,7 @@ function runTests(newToken, _accounts) {
it("upt012 should upgradeToAndCall while upgrader is blacklisted", async () => {
await token.blacklist(proxyOwnerAccount, { from: blacklisterAccount });
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
const initializeData = encodeCall(
"initV2",
["bool", "address", "uint256"],
@@ -424,7 +463,7 @@ function runTests(newToken, _accounts) {
});
it("upt013 should upgradeToAndCall while new logic is blacklisted", async () => {
- const upgradedToken = await UpgradedFiatTokenNewFields.new();
+ const upgradedToken = await deployUpgradedFiatTokenNewFields(version);
await token.blacklist(upgradedToken.address, { from: blacklisterAccount });
const initializeData = encodeCall(
@@ -444,7 +483,7 @@ function runTests(newToken, _accounts) {
});
it("upt014 should upgradeTo while new logic is blacklisted", async () => {
- const upgradedToken = await UpgradedFiatToken.new();
+ const upgradedToken = await newToken();
await token.blacklist(upgradedToken.address, { from: blacklisterAccount });
const tokenConfig = await upgradeTo(
@@ -452,12 +491,12 @@ function runTests(newToken, _accounts) {
upgradedToken,
proxyOwnerAccount
);
- const newToken = tokenConfig.token;
+ const proxiedToken = tokenConfig.token;
const customVars = [
{ variable: "proxiedTokenAddress", expectedValue: upgradedToken.address },
];
- await checkVariables([newToken], [customVars]);
+ await checkVariables([proxiedToken], [customVars]);
});
}
diff --git a/test/v2/FiatTokenV2.test.ts b/test/v2/FiatTokenV2.test.ts
index 472923690..0226d8a92 100644
--- a/test/v2/FiatTokenV2.test.ts
+++ b/test/v2/FiatTokenV2.test.ts
@@ -1,22 +1,41 @@
-import { behavesLikeRescuable } from "../v1.1/Rescuable.behavior";
-import { FiatTokenV2Instance, RescuableInstance } from "../../@types/generated";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { FiatTokenV2Instance } from "../../@types/generated";
import { usesOriginalStorageSlotPositions } from "../helpers/storageSlots.behavior";
-import { hasSafeAllowance } from "./safeAllowance.behavior";
-import { hasGasAbstraction } from "./GasAbstraction/GasAbstraction.behavior";
-import { expectRevert } from "../helpers";
+import { linkLibraryToTokenContract } from "../helpers";
+import { HARDHAT_ACCOUNTS } from "../helpers/constants";
+import { behavesLikeFiatTokenV2 } from "./v2.behavior";
const FiatTokenV2 = artifacts.require("FiatTokenV2");
-contract("FiatTokenV2", (accounts) => {
- const fiatTokenOwner = accounts[9];
+describe("FiatTokenV2", () => {
let fiatToken: FiatTokenV2Instance;
- let domainSeparator: string;
- let chainId: number;
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[9];
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2);
+ });
beforeEach(async () => {
fiatToken = await FiatTokenV2.new();
await fiatToken.initialize(
- "USD Coin",
+ "USDC",
"USDC",
"USD",
6,
@@ -25,55 +44,12 @@ contract("FiatTokenV2", (accounts) => {
fiatTokenOwner,
fiatTokenOwner
);
- await fiatToken.initializeV2("USD Coin", { from: fiatTokenOwner });
-
- // hardcode chainId to be 1 due to ganache bug
- // https://github.com/trufflesuite/ganache/issues/1643
- // chainId = await web3.eth.getChainId();
- chainId = 1;
-
- domainSeparator = web3.utils.keccak256(
- web3.eth.abi.encodeParameters(
- ["bytes32", "bytes32", "bytes32", "uint256", "address"],
- [
- web3.utils.keccak256(
- "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
- ),
- web3.utils.keccak256("USD Coin"),
- web3.utils.keccak256("2"),
- chainId,
- fiatToken.address,
- ]
- )
- );
+ await fiatToken.initializeV2("USDC", { from: fiatTokenOwner });
});
- behavesLikeRescuable(() => fiatToken as RescuableInstance, accounts);
-
+ behavesLikeFiatTokenV2(2, () => fiatToken);
usesOriginalStorageSlotPositions({
Contract: FiatTokenV2,
version: 2,
- accounts,
- });
-
- it("has the expected domain separator", async () => {
- expect(await fiatToken.DOMAIN_SEPARATOR()).to.equal(domainSeparator);
- });
-
- hasSafeAllowance(() => fiatToken, fiatTokenOwner, accounts);
-
- hasGasAbstraction(
- () => fiatToken,
- () => domainSeparator,
- fiatTokenOwner,
- accounts
- );
-
- it("disallows calling initializeV2 twice", async () => {
- // It was called once in beforeEach. Try to call again.
- await expectRevert(
- fiatToken.initializeV2("Not USD Coin", { from: fiatTokenOwner }),
- "contract is already initialized"
- );
});
});
diff --git a/test/v2/FiatTokenV2_1.test.ts b/test/v2/FiatTokenV2_1.test.ts
new file mode 100644
index 000000000..3fd7cc30b
--- /dev/null
+++ b/test/v2/FiatTokenV2_1.test.ts
@@ -0,0 +1,112 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { FiatTokenV2_1Instance } from "../../@types/generated";
+import { expectRevert, linkLibraryToTokenContract } from "../helpers";
+import { HARDHAT_ACCOUNTS } from "../helpers/constants";
+import { usesOriginalStorageSlotPositions } from "../helpers/storageSlots.behavior";
+import { behavesLikeFiatTokenV2 } from "./v2.behavior";
+
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+
+describe("FiatTokenV2_1", () => {
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[9];
+
+ let fiatToken: FiatTokenV2_1Instance;
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2_1);
+ });
+
+ beforeEach(async () => {
+ fiatToken = await FiatTokenV2_1.new();
+ await fiatToken.initialize(
+ "USDC",
+ "USDC",
+ "USD",
+ 6,
+ fiatTokenOwner,
+ fiatTokenOwner,
+ fiatTokenOwner,
+ fiatTokenOwner
+ );
+ await fiatToken.initializeV2("USDC", { from: fiatTokenOwner });
+ });
+
+ behavesLikeFiatTokenV2(2.1, () => fiatToken);
+ usesOriginalStorageSlotPositions({
+ Contract: FiatTokenV2_1,
+ version: 2.1,
+ });
+
+ describe("initializeV2_1", () => {
+ const [, user, lostAndFound] = HARDHAT_ACCOUNTS;
+
+ beforeEach(async () => {
+ await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
+ from: fiatTokenOwner,
+ });
+ await fiatToken.mint(user, 100e6, { from: fiatTokenOwner });
+ });
+
+ it("transfers locked funds to a given address", async () => {
+ // send tokens to the contract address
+ await fiatToken.transfer(fiatToken.address, 100e6, { from: user });
+
+ expect(
+ (await fiatToken.balanceOf(fiatToken.address)).toNumber()
+ ).to.equal(100e6);
+
+ // initialize v2.1
+ await fiatToken.initializeV2_1(lostAndFound, { from: fiatTokenOwner });
+
+ expect(
+ (await fiatToken.balanceOf(fiatToken.address)).toNumber()
+ ).to.equal(0);
+
+ expect((await fiatToken.balanceOf(lostAndFound)).toNumber()).to.equal(
+ 100e6
+ );
+ });
+
+ it("blocks transfers to the contract address", async () => {
+ await fiatToken.initializeV2_1(lostAndFound, { from: fiatTokenOwner });
+
+ expect(await fiatToken.isBlacklisted(fiatToken.address)).to.equal(true);
+
+ await expectRevert(
+ fiatToken.transfer(fiatToken.address, 100e6, { from: user }),
+ "account is blacklisted"
+ );
+ });
+
+ it("disallows calling initializeV2_1 twice", async () => {
+ await fiatToken.initializeV2_1(lostAndFound, { from: fiatTokenOwner });
+
+ await expectRevert(
+ fiatToken.initializeV2_1(lostAndFound, { from: fiatTokenOwner })
+ );
+ });
+ });
+
+ describe("version", () => {
+ it("returns the version string", async () => {
+ expect(await fiatToken.version()).to.equal("2");
+ });
+ });
+});
diff --git a/test/v2/FiatTokenV2_2.test.ts b/test/v2/FiatTokenV2_2.test.ts
new file mode 100644
index 000000000..397b73014
--- /dev/null
+++ b/test/v2/FiatTokenV2_2.test.ts
@@ -0,0 +1,304 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import BN from "bn.js";
+import {
+ AnyFiatTokenV2Instance,
+ FiatTokenV2_2InstanceExtended,
+ FiatTokenCeloV2_2InstanceExtended,
+} from "../../@types/AnyFiatTokenV2Instance";
+import {
+ expectRevert,
+ generateAccounts,
+ initializeToVersion,
+ linkLibraryToTokenContract,
+} from "../helpers";
+import { HARDHAT_ACCOUNTS, POW_2_255_BN } from "../helpers/constants";
+import {
+ STORAGE_SLOT_NUMBERS,
+ addressMappingSlot,
+ readSlot,
+ usesOriginalStorageSlotPositions,
+} from "../helpers/storageSlots.behavior";
+import { behavesLikeFiatTokenV2 } from "./v2.behavior";
+import {
+ SignatureBytesType,
+ permitSignature,
+ permitSignatureV22,
+ transferWithAuthorizationSignature,
+ transferWithAuthorizationSignatureV22,
+ cancelAuthorizationSignature,
+ cancelAuthorizationSignatureV22,
+ receiveWithAuthorizationSignature,
+ receiveWithAuthorizationSignatureV22,
+} from "./GasAbstraction/helpers";
+import { encodeCall } from "../v1/helpers/tokenTest";
+import { behavesLikeFiatTokenV22 } from "./v2_2.behavior";
+
+const FiatTokenProxy = artifacts.require("FiatTokenProxy");
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+const FiatTokenV2_2 = artifacts.require("FiatTokenV2_2");
+
+describe("FiatTokenV2_2", () => {
+ const newSymbol = "USDCUSDC";
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[9];
+ const lostAndFound = HARDHAT_ACCOUNTS[2];
+ const proxyOwnerAccount = HARDHAT_ACCOUNTS[14];
+
+ let fiatToken: FiatTokenV2_2InstanceExtended;
+
+ const getFiatToken = (
+ signatureBytesType: SignatureBytesType
+ ): (() => AnyFiatTokenV2Instance) => {
+ return () => {
+ initializeOverloadedMethods(fiatToken, signatureBytesType);
+ return fiatToken;
+ };
+ };
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2_1);
+ await linkLibraryToTokenContract(FiatTokenV2_2);
+ });
+
+ beforeEach(async () => {
+ fiatToken = await FiatTokenV2_2.new();
+ await initializeToVersion(fiatToken, "2.1", fiatTokenOwner, lostAndFound);
+ });
+
+ describe("initializeV2_2", () => {
+ it("disallows calling initializeV2_2 twice", async () => {
+ await fiatToken.initializeV2_2([], newSymbol);
+ await expectRevert(fiatToken.initializeV2_2([], newSymbol));
+ });
+
+ it("should update symbol", async () => {
+ await fiatToken.initializeV2_2([], newSymbol);
+ expect(await fiatToken.symbol()).to.eql(newSymbol);
+ });
+
+ it("should blacklist all accountsToBlacklist", async () => {
+ const [unblacklistedAccount, ...accountsToBlacklist] = generateAccounts(
+ 10
+ );
+
+ // Prepare a proxy that's tied to a V2_1 implementation so that we can blacklist
+ // the account in _deprecatedBlacklisted first.
+ const _fiatTokenV2_1 = await FiatTokenV2_1.new();
+ const _proxy = await FiatTokenProxy.new(_fiatTokenV2_1.address, {
+ from: proxyOwnerAccount,
+ });
+ const _proxyAsV2_1 = await FiatTokenV2_1.at(_proxy.address);
+ await initializeToVersion(
+ _proxyAsV2_1,
+ "2.1",
+ fiatTokenOwner,
+ lostAndFound
+ );
+ await Promise.all(
+ accountsToBlacklist.map((a) =>
+ _proxyAsV2_1.blacklist(a, { from: fiatTokenOwner })
+ )
+ );
+
+ // Sanity check that _deprecatedBlacklisted is set, and balanceAndBlacklistStates is not set for
+ // every accountsToBlacklist.
+ expect(
+ (
+ await readDeprecatedBlacklisted(_proxy.address, accountsToBlacklist)
+ ).every((result) => result === 1)
+ ).to.be.true;
+ expect(
+ (
+ await readBalanceAndBlacklistStates(
+ _proxy.address,
+ accountsToBlacklist
+ )
+ ).every((result) => result.eq(new BN(0)))
+ ).to.be.true;
+
+ // Sanity check that _deprecatedBlacklisted is set, and balanceAndBlacklistStates is not set
+ // for `address(this)`
+ expect(
+ (await readDeprecatedBlacklisted(_proxy.address, [_proxy.address]))[0]
+ ).to.equal(1);
+ expect(
+ (
+ await readBalanceAndBlacklistStates(_proxy.address, [_proxy.address])
+ )[0].eq(new BN(0))
+ ).to.be.true;
+
+ // Call the initializeV2_2 function through an upgrade call.
+ const initializeData = encodeCall(
+ "initializeV2_2",
+ ["address[]", "string"],
+ [accountsToBlacklist, newSymbol]
+ );
+ await _proxy.upgradeToAndCall(fiatToken.address, initializeData, {
+ from: proxyOwnerAccount,
+ });
+
+ // Validate that isBlacklisted returns true for every accountsToBlacklist.
+ const _proxyAsV2_2 = await FiatTokenV2_2.at(_proxy.address);
+ const areAccountsBlacklisted = await Promise.all(
+ accountsToBlacklist.map((account) =>
+ _proxyAsV2_2.isBlacklisted(account)
+ )
+ );
+ expect(areAccountsBlacklisted.every((b: boolean) => b)).to.be.true;
+
+ // Validate that _deprecatedBlacklisted is unset, and balanceAndBlacklistStates is set for every
+ // accountsToBlacklist.
+ expect(
+ (
+ await readDeprecatedBlacklisted(_proxy.address, accountsToBlacklist)
+ ).every((result) => result === 0)
+ ).to.be.true;
+ expect(
+ (
+ await readBalanceAndBlacklistStates(
+ _proxy.address,
+ accountsToBlacklist
+ )
+ ).every((result) => result.eq(POW_2_255_BN))
+ ).to.be.true;
+
+ // Validate that _deprecatedBlacklisted is unset, and balanceAndBlacklistStates is set for
+ // `address(this)`
+ expect(
+ (await readDeprecatedBlacklisted(_proxy.address, [_proxy.address]))[0]
+ ).to.equal(0);
+ expect(
+ (
+ await readBalanceAndBlacklistStates(_proxy.address, [_proxy.address])
+ )[0].eq(POW_2_255_BN)
+ ).to.be.true;
+
+ // Sanity check that an unblacklisted account does not get blacklisted.
+ expect(await _proxyAsV2_2.isBlacklisted(unblacklistedAccount)).to.be
+ .false;
+ });
+
+ it("should revert if an accountToBlacklist was not blacklisted", async () => {
+ const accountsToBlacklist = generateAccounts(1);
+ await expectRevert(
+ fiatToken.initializeV2_2(accountsToBlacklist, newSymbol),
+ "FiatTokenV2_2: Blacklisting previously unblacklisted account!"
+ );
+
+ // Sanity check that the account is not blacklisted after revert.
+ expect(await fiatToken.isBlacklisted(accountsToBlacklist[0])).to.be.false;
+ });
+ });
+
+ describe("initialized contract", () => {
+ beforeEach(async () => {
+ await fiatToken.initializeV2_2([], newSymbol);
+ });
+
+ behavesLikeFiatTokenV2(2.2, getFiatToken(SignatureBytesType.Unpacked));
+
+ behavesLikeFiatTokenV22(getFiatToken(SignatureBytesType.Packed));
+ usesOriginalStorageSlotPositions({
+ Contract: FiatTokenV2_2,
+ version: 2.2,
+ });
+ });
+});
+
+/**
+ * With v2.2 we introduce overloaded functions for `permit`,
+ * `transferWithAuthorization`, `receiveWithAuthorization`,
+ * and `cancelAuthorization`.
+ *
+ * Since function overloading isn't supported by Javascript,
+ * the typechain library generates type interfaces for overloaded functions differently.
+ * For instance, we can no longer access the `permit` function with
+ * `fiattoken.permit`. Instead, we need to need to use the full function signature e.g.
+ * `fiattoken.methods["permit(address,address,uint256,uint256,uint8,bytes32,bytes32)"]` OR
+ * `fiattoken.methods["permit(address,address,uint256,uint256,bytes)"]` (v22 interface).
+ *
+ * To preserve type-coherence and reuse test suites written for v2 & v2.1 contracts,
+ * here we re-assign the overloaded method definition to the method name shorthand.
+ */
+export function initializeOverloadedMethods(
+ fiatToken: FiatTokenV2_2InstanceExtended | FiatTokenCeloV2_2InstanceExtended,
+ signatureBytesType: SignatureBytesType
+): void {
+ if (signatureBytesType == SignatureBytesType.Unpacked) {
+ fiatToken.permit = fiatToken.methods[permitSignature];
+ fiatToken.transferWithAuthorization =
+ fiatToken.methods[transferWithAuthorizationSignature];
+ fiatToken.receiveWithAuthorization =
+ fiatToken.methods[receiveWithAuthorizationSignature];
+ fiatToken.cancelAuthorization =
+ fiatToken.methods[cancelAuthorizationSignature];
+ } else {
+ fiatToken.permit = fiatToken.methods[permitSignatureV22];
+ fiatToken.transferWithAuthorization =
+ fiatToken.methods[transferWithAuthorizationSignatureV22];
+ fiatToken.receiveWithAuthorization =
+ fiatToken.methods[receiveWithAuthorizationSignatureV22];
+ fiatToken.cancelAuthorization =
+ fiatToken.methods[cancelAuthorizationSignatureV22];
+ }
+}
+
+/**
+ * Helper method to read the _deprecatedBlacklisted map.
+ * @param proxyOrImplementation the address of the proxy or implementation contract.
+ * @param accounts the accounts to read states for.
+ * @returns the results (in order) from reading the map.
+ */
+async function readDeprecatedBlacklisted(
+ proxyOrImplementation: string,
+ accounts: string[]
+): Promise {
+ return (
+ await Promise.all(
+ accounts.map((a) =>
+ readSlot(
+ proxyOrImplementation,
+ addressMappingSlot(a, STORAGE_SLOT_NUMBERS._deprecatedBlacklisted)
+ )
+ )
+ )
+ ).map((result) => parseInt(result, 16));
+}
+
+/**
+ * Helper method to read the balanceAndBlacklistStates map.
+ * @param proxyOrImplementation the address of the proxy or implementation contract.
+ * @param accounts the accounts to read states for.
+ * @returns the results (in order) from reading the map.
+ */
+async function readBalanceAndBlacklistStates(
+ proxyOrImplementation: string,
+ accounts: string[]
+): Promise {
+ return (
+ await Promise.all(
+ accounts.map((a) =>
+ readSlot(
+ proxyOrImplementation,
+ addressMappingSlot(a, STORAGE_SLOT_NUMBERS.balanceAndBlacklistStates)
+ )
+ )
+ )
+ ).map((result) => new BN(result.slice(2), 16));
+}
diff --git a/test/v2/GasAbstraction/GasAbstraction.behavior.ts b/test/v2/GasAbstraction/GasAbstraction.behavior.ts
index 797965f4b..e7508ce20 100644
--- a/test/v2/GasAbstraction/GasAbstraction.behavior.ts
+++ b/test/v2/GasAbstraction/GasAbstraction.behavior.ts
@@ -1,33 +1,37 @@
-import { FiatTokenV2Instance } from "../../../@types/generated";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { TestParams } from "./helpers";
import { testTransferWithAuthorization } from "./testTransferWithAuthorization";
-import { testApproveWithAuthorization } from "./testApproveWithAuthorization";
-import { testIncreaseAllowanceWithAuthorization } from "./testIncreaseAllowanceWithAuthorization";
-import { testDecreaseAllowanceWithAuthorization } from "./testDecreaseAllowanceWithAuthorization";
import { testCancelAuthorization } from "./testCancelAuthorization";
import { testPermit } from "./testPermit";
-import { testTransferWithMultipleAuthorizations } from "./testTransferWithMultipleAuthorizations";
+import { testReceiveWithAuthorization } from "./testReceiveWithAuthorization";
-export function hasGasAbstraction(
- getFiatToken: () => FiatTokenV2Instance,
- getDomainSeparator: () => string,
- fiatTokenOwner: string,
- accounts: Truffle.Accounts
-): void {
+export function hasGasAbstraction(testParams: TestParams): void {
describe("GasAbstraction", () => {
- const testParams: TestParams = {
- getFiatToken,
- getDomainSeparator,
- fiatTokenOwner,
- accounts,
- };
+ describe("EIP-3009", () => {
+ testTransferWithAuthorization(testParams);
+ testReceiveWithAuthorization(testParams);
+ testCancelAuthorization(testParams);
+ });
- testTransferWithAuthorization(testParams);
- testApproveWithAuthorization(testParams);
- testIncreaseAllowanceWithAuthorization(testParams);
- testDecreaseAllowanceWithAuthorization(testParams);
- testCancelAuthorization(testParams);
- testPermit(testParams);
- testTransferWithMultipleAuthorizations(testParams);
+ describe("EIP-2612", () => {
+ testPermit(testParams);
+ });
});
}
diff --git a/test/v2/GasAbstraction/helpers.ts b/test/v2/GasAbstraction/helpers.ts
index 8baface84..c91bc752e 100644
--- a/test/v2/GasAbstraction/helpers.ts
+++ b/test/v2/GasAbstraction/helpers.ts
@@ -1,27 +1,84 @@
-import { FiatTokenV2Instance } from "../../../@types/generated";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { AnyFiatTokenV2Instance } from "../../../@types/AnyFiatTokenV2Instance";
+import { MockERC1271WalletInstance } from "../../../@types/generated";
import { Signature, ecSign, strip0x } from "../../helpers";
+import { packSignature } from "../../helpers";
+
+export enum WalletType {
+ EOA = "EOA",
+ AA = "AA",
+}
+
+export enum SignatureBytesType {
+ Packed = "Packed", // Signature provided in the format of a single byte array, packed in the order of r, s, v for EOA wallets
+ Unpacked = "Unpacked", // Signature values provided as separate inputs (v, r, s)
+}
export interface TestParams {
- getFiatToken: () => FiatTokenV2Instance;
+ version: number;
+ getFiatToken: () => AnyFiatTokenV2Instance;
getDomainSeparator: () => string;
- fiatTokenOwner: string;
- accounts: Truffle.Accounts;
+ signerWalletType: WalletType;
+ signatureBytesType: SignatureBytesType;
+ getERC1271Wallet: (owner: string) => Promise;
}
-export const transferWithAuthorizationTypeHash = web3.utils.keccak256(
- "TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)"
-);
+export function makeDomainSeparator(
+ name: string,
+ version: string,
+ chainId: number,
+ verifyingContract: string
+): string {
+ return web3.utils.keccak256(
+ web3.eth.abi.encodeParameters(
+ ["bytes32", "bytes32", "bytes32", "uint256", "address"],
+ [
+ web3.utils.keccak256(
+ "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
+ ),
+ web3.utils.keccak256(name),
+ web3.utils.keccak256(version),
+ chainId,
+ verifyingContract,
+ ]
+ )
+ );
+}
-export const approveWithAuthorizationTypeHash = web3.utils.keccak256(
- "ApproveWithAuthorization(address owner,address spender,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)"
-);
+export function prepareSignature(
+ signature: Signature,
+ signatureBytesType: SignatureBytesType
+): Array {
+ if (signatureBytesType == SignatureBytesType.Unpacked) {
+ return [signature.v, signature.r, signature.s];
+ } else {
+ return [packSignature(signature)];
+ }
+}
-export const increaseAllowanceWithAuthorizationTypeHash = web3.utils.keccak256(
- "IncreaseAllowanceWithAuthorization(address owner,address spender,uint256 increment,uint256 validAfter,uint256 validBefore,bytes32 nonce)"
+export const transferWithAuthorizationTypeHash = web3.utils.keccak256(
+ "TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)"
);
-export const decreaseAllowanceWithAuthorizationTypeHash = web3.utils.keccak256(
- "DecreaseAllowanceWithAuthorization(address owner,address spender,uint256 decrement,uint256 validAfter,uint256 validBefore,bytes32 nonce)"
+export const receiveWithAuthorizationTypeHash = web3.utils.keccak256(
+ "ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)"
);
export const cancelAuthorizationTypeHash = web3.utils.keccak256(
@@ -32,6 +89,36 @@ export const permitTypeHash = web3.utils.keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
);
+/**
+ * Overloaded method signatures
+ */
+export const permitSignature =
+ "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)";
+
+export const permitSignatureV22 =
+ "permit(address,address,uint256,uint256,bytes)";
+
+export const transferWithAuthorizationSignature =
+ "transferWithAuthorization(address,address,uint256,uint256,uint256,bytes32,uint8,bytes32,bytes32)";
+
+export const transferWithAuthorizationSignatureV22 =
+ "transferWithAuthorization(address,address,uint256,uint256,uint256,bytes32,bytes)";
+
+export const receiveWithAuthorizationSignature =
+ "receiveWithAuthorization(address,address,uint256,uint256,uint256,bytes32,uint8,bytes32,bytes32)";
+
+export const receiveWithAuthorizationSignatureV22 =
+ "receiveWithAuthorization(address,address,uint256,uint256,uint256,bytes32,bytes)";
+
+export const cancelAuthorizationSignature =
+ "cancelAuthorization(address,bytes32,uint8,bytes32,bytes32)";
+
+export const cancelAuthorizationSignatureV22 =
+ "cancelAuthorization(address,bytes32,bytes)";
+
+/**
+ * Signature generation helper functions
+ */
export function signTransferAuthorization(
from: string,
to: string,
@@ -51,9 +138,9 @@ export function signTransferAuthorization(
);
}
-export function signApproveAuthorization(
- owner: string,
- spender: string,
+export function signReceiveAuthorization(
+ from: string,
+ to: string,
value: number | string,
validAfter: number | string,
validBefore: number | string,
@@ -63,47 +150,9 @@ export function signApproveAuthorization(
): Signature {
return signEIP712(
domainSeparator,
- approveWithAuthorizationTypeHash,
- ["address", "address", "uint256", "uint256", "uint256", "bytes32"],
- [owner, spender, value, validAfter, validBefore, nonce],
- privateKey
- );
-}
-
-export function signIncreaseAllowanceAuthorization(
- owner: string,
- spender: string,
- increment: number | string,
- validAfter: number | string,
- validBefore: number | string,
- nonce: string,
- domainSeparator: string,
- privateKey: string
-): Signature {
- return signEIP712(
- domainSeparator,
- increaseAllowanceWithAuthorizationTypeHash,
+ receiveWithAuthorizationTypeHash,
["address", "address", "uint256", "uint256", "uint256", "bytes32"],
- [owner, spender, increment, validAfter, validBefore, nonce],
- privateKey
- );
-}
-
-export function signDecreaseAllowanceAuthorization(
- owner: string,
- spender: string,
- decrement: number | string,
- validAfter: number | string,
- validBefore: number | string,
- nonce: string,
- domainSeparator: string,
- privateKey: string
-): Signature {
- return signEIP712(
- domainSeparator,
- decreaseAllowanceWithAuthorizationTypeHash,
- ["address", "address", "uint256", "uint256", "uint256", "bytes32"],
- [owner, spender, decrement, validAfter, validBefore, nonce],
+ [from, to, value, validAfter, validBefore, nonce],
privateKey
);
}
diff --git a/test/v2/GasAbstraction/testApproveWithAuthorization.ts b/test/v2/GasAbstraction/testApproveWithAuthorization.ts
deleted file mode 100644
index 27444ccda..000000000
--- a/test/v2/GasAbstraction/testApproveWithAuthorization.ts
+++ /dev/null
@@ -1,511 +0,0 @@
-import crypto from "crypto";
-import { FiatTokenV2Instance } from "../../../@types/generated";
-import {
- AuthorizationUsed,
- Approval,
-} from "../../../@types/generated/FiatTokenV2";
-import {
- ACCOUNTS_AND_KEYS,
- MAX_UINT256,
- ZERO_ADDRESS,
-} from "../../helpers/constants";
-import { expectRevert, hexStringFromBuffer } from "../../helpers";
-import {
- approveWithAuthorizationTypeHash,
- signApproveAuthorization,
- TestParams,
- signTransferAuthorization,
-} from "./helpers";
-
-export function testApproveWithAuthorization({
- getFiatToken,
- getDomainSeparator,
- fiatTokenOwner,
- accounts,
-}: TestParams): void {
- describe("approveWithAuthorization", () => {
- let fiatToken: FiatTokenV2Instance;
- let domainSeparator: string;
- const [alice, bob] = ACCOUNTS_AND_KEYS;
- const charlie = accounts[1];
- let nonce: string;
-
- const initialBalance = 10e6;
- const approveParams = {
- owner: alice.address,
- spender: bob.address,
- value: 7e6,
- validAfter: 0,
- validBefore: MAX_UINT256,
- };
-
- beforeEach(async () => {
- fiatToken = getFiatToken();
- domainSeparator = getDomainSeparator();
- nonce = hexStringFromBuffer(crypto.randomBytes(32));
- await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
- from: fiatTokenOwner,
- });
- await fiatToken.mint(approveParams.owner, initialBalance, {
- from: fiatTokenOwner,
- });
- });
-
- it("has the expected type hash", async () => {
- expect(await fiatToken.APPROVE_WITH_AUTHORIZATION_TYPEHASH()).to.equal(
- approveWithAuthorizationTypeHash
- );
- });
-
- it("grants allowance when a valid authorization is given", async () => {
- const { owner, spender, value, validAfter, validBefore } = approveParams;
- // create a signed authorization to grant Bob permission to spend
- // Alice's funds on behalf, and sign with Alice's key
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // check that the allowance is initially zero
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- 0
- );
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(0);
-
- // a third-party, Charlie (not Alice) submits the authorization
- const result = await fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // check that allowance is updated
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- value
- );
-
- // check that AuthorizationUsed event is emitted
- const log0 = result.logs[0] as Truffle.TransactionLog;
- expect(log0.event).to.equal("AuthorizationUsed");
- expect(log0.args[0]).to.equal(owner);
- expect(log0.args[1]).to.equal(nonce);
-
- // check that Approval event is emitted
- const log1 = result.logs[1] as Truffle.TransactionLog;
- expect(log1.event).to.equal("Approval");
- expect(log1.args[0]).to.equal(owner);
- expect(log1.args[1]).to.equal(spender);
- expect(log1.args[2].toNumber()).to.equal(value);
-
- // check that the authorization state is now 1 = Used
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(1);
- });
-
- it("reverts if the signature does not match given parameters", async () => {
- const { owner, spender, value, validAfter, validBefore } = approveParams;
- // create a signed authorization
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to cheat by claiming the approved amount is double
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value * 2, // pass incorrect value
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the signature is not signed with the right key", async () => {
- const { owner, spender, value, validAfter, validBefore } = approveParams;
- // create a signed authorization to grant Bob permission to spend
- // Alice's funds on behalf, but sign with Bob's key instead of Alice's
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- bob.key
- );
-
- // try to cheat by submitting the authorization that is signed by a
- // wrong person
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the authorization is not yet valid", async () => {
- const { owner, spender, value, validBefore } = approveParams;
- // create a signed authorization that won't be valid until 10 seconds
- // later
- const validAfter = Math.floor(Date.now() / 1000) + 10;
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization early
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is not yet valid"
- );
- });
-
- it("reverts if the authorization is expired", async () => {
- const { owner, spender, value, validAfter } = approveParams;
- // create a signed authorization that won't be valid until 10 seconds
- // later
- const validBefore = Math.floor(Date.now() / 1000);
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization that is expired
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is expired"
- );
- });
-
- it("reverts if the authorization has already been used", async () => {
- const { owner, spender, value, validAfter, validBefore } = approveParams;
- // create a signed authorization
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // submit the authorization
- await fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // try to submit the authorization again
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("reverts if the authorization has a nonce that has already been used by the signer", async () => {
- const { owner, spender, value, validAfter, validBefore } = approveParams;
- // create a signed authorization
- const authorization = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // submit the authorization
- await fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- authorization.v,
- authorization.r,
- authorization.s,
- { from: charlie }
- );
-
- // create another signed authorization with the same nonce, but
- // with different parameters
- const authorization2 = signApproveAuthorization(
- owner,
- spender,
- 1e6,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization again
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- 1e6,
- validAfter,
- validBefore,
- nonce,
- authorization2.v,
- authorization2.r,
- authorization2.s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("reverts if the authorization includes invalid approval parameters", async () => {
- const { owner, value, validAfter, validBefore } = approveParams;
- // create a signed authorization that attempts to grant allowance to the
- // zero address
- const spender = ZERO_ADDRESS;
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization with invalid approval parameters
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "approve to the zero address"
- );
- });
-
- it("reverts if the authorization is not for an approval", async () => {
- const {
- owner: from,
- spender: to,
- value,
- validAfter,
- validBefore,
- } = approveParams;
- // create a signed authorization for a transfer
- const { v, r, s } = signTransferAuthorization(
- from,
- to,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the transfer authorization
- await expectRevert(
- fiatToken.approveWithAuthorization(
- from,
- to,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the contract is paused", async () => {
- const { owner, spender, value, validAfter, validBefore } = approveParams;
- // create a signed authorization
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // pause the contract
- await fiatToken.pause({ from: fiatTokenOwner });
-
- // try to submit the authorization
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "paused"
- );
- });
-
- it("reverts if the owner or the spender is blacklisted", async () => {
- const { owner, spender, value, validAfter, validBefore } = approveParams;
- // create a signed authorization
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // owner is blacklisted
- await fiatToken.blacklist(owner, { from: fiatTokenOwner });
-
- const submitTx = () =>
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // try to submit the authorization
- await expectRevert(submitTx(), "account is blacklisted");
-
- // spender is blacklisted
- await fiatToken.unBlacklist(owner, { from: fiatTokenOwner });
- await fiatToken.blacklist(spender, { from: fiatTokenOwner });
-
- // try to submit the authorization
- await expectRevert(submitTx(), "account is blacklisted");
- });
- });
-}
diff --git a/test/v2/GasAbstraction/testCancelAuthorization.ts b/test/v2/GasAbstraction/testCancelAuthorization.ts
index 6e19c070c..e3feec894 100644
--- a/test/v2/GasAbstraction/testCancelAuthorization.ts
+++ b/test/v2/GasAbstraction/testCancelAuthorization.ts
@@ -1,38 +1,79 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import crypto from "crypto";
-import { FiatTokenV2Instance } from "../../../@types/generated";
-import { ACCOUNTS_AND_KEYS, MAX_UINT256 } from "../../helpers/constants";
+import {
+ ACCOUNTS_AND_KEYS,
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_HEX,
+} from "../../helpers/constants";
import { expectRevert, hexStringFromBuffer } from "../../helpers";
import {
cancelAuthorizationTypeHash,
signTransferAuthorization,
- signApproveAuthorization,
signCancelAuthorization,
- signIncreaseAllowanceAuthorization,
- signDecreaseAllowanceAuthorization,
TestParams,
+ WalletType,
+ prepareSignature,
} from "./helpers";
+import { AnyFiatTokenV2Instance } from "../../../@types/AnyFiatTokenV2Instance";
+import { MockERC1271WalletInstance } from "../../../@types/generated";
export function testCancelAuthorization({
getFiatToken,
+ getERC1271Wallet,
getDomainSeparator,
- fiatTokenOwner,
- accounts,
+ signerWalletType,
+ signatureBytesType,
}: TestParams): void {
- describe("cancelAuthorization", () => {
- let fiatToken: FiatTokenV2Instance;
- let domainSeparator: string;
+ describe(`cancelAuthorization with ${signerWalletType} wallet, ${signatureBytesType} signature interface`, async () => {
const [alice, bob] = ACCOUNTS_AND_KEYS;
- const charlie = accounts[1];
- let nonce: string;
+ const charlie = HARDHAT_ACCOUNTS[1];
+ const nonce = hexStringFromBuffer(crypto.randomBytes(32));
+
+ let fiatTokenOwner: string;
+ let fiatToken: AnyFiatTokenV2Instance;
+ let aliceWallet: MockERC1271WalletInstance;
+ let domainSeparator: string;
+ let from: string;
+
+ before(async () => {
+ fiatTokenOwner = await getFiatToken().owner();
+ });
beforeEach(async () => {
fiatToken = getFiatToken();
+ aliceWallet = await getERC1271Wallet(alice.address);
domainSeparator = getDomainSeparator();
- nonce = hexStringFromBuffer(crypto.randomBytes(32));
+
+ // Initialize `from` address either as Alice's EOA address or Alice's wallet address
+ if (signerWalletType == WalletType.AA) {
+ from = aliceWallet.address;
+ } else {
+ from = alice.address;
+ }
+
await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
from: fiatTokenOwner,
});
- await fiatToken.mint(alice.address, 10e6, { from: fiatTokenOwner });
+ await fiatToken.mint(from, 10e6, {
+ from: fiatTokenOwner,
+ });
});
it("has the expected type hash", async () => {
@@ -42,11 +83,10 @@ export function testCancelAuthorization({
});
it("cancels unused transfer authorization if signature is valid", async () => {
- const from = alice.address;
const to = bob.address;
const value = 7e6;
const validAfter = 0;
- const validBefore = MAX_UINT256;
+ const validBefore = MAX_UINT256_HEX;
// create a signed authorization
const authorization = signTransferAuthorization(
@@ -68,25 +108,19 @@ export function testCancelAuthorization({
alice.key
);
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(0);
+ // check that the authorization state is false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
// cancel the authorization
await fiatToken.cancelAuthorization(
from,
nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
+ ...prepareSignature(cancellation, signatureBytesType),
{ from: charlie }
);
- // check that the authorization state is now 2 = Canceled
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(2);
+ // check that the authorization state is now true
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(true);
// attempt to use the canceled authorization
await expectRevert(
@@ -97,204 +131,7 @@ export function testCancelAuthorization({
validAfter,
validBefore,
nonce,
- authorization.v,
- authorization.r,
- authorization.s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("cancels unused approve authorization if signature is valid", async () => {
- const owner = alice.address;
- const spender = bob.address;
- const value = 7e6;
- const validAfter = 0;
- const validBefore = MAX_UINT256;
-
- // create a signed authorization
- const authorization = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // create cancellation
- const cancellation = signCancelAuthorization(
- owner,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(0);
-
- // cancel the authorization
- await fiatToken.cancelAuthorization(
- owner,
- nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
- { from: charlie }
- );
-
- // check that the authorization state is now 2 = Canceled
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(2);
-
- // attempt to use the canceled authorization
- await expectRevert(
- fiatToken.approveWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- authorization.v,
- authorization.r,
- authorization.s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("cancels unused increaseAllowance authorization if signature is valid", async () => {
- const owner = alice.address;
- const spender = bob.address;
- const value = 1e6;
- const validAfter = 0;
- const validBefore = MAX_UINT256;
-
- // create a signed authorization
- const authorization = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // create cancellation
- const cancellation = signCancelAuthorization(
- owner,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(0);
-
- // cancel the authorization
- await fiatToken.cancelAuthorization(
- owner,
- nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
- { from: charlie }
- );
-
- // check that the authorization state is now 2 = Canceled
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(2);
-
- // attempt to use the canceled authorization
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- authorization.v,
- authorization.r,
- authorization.s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("cancels unused decreaseAllowance authorization if signature is valid", async () => {
- const owner = alice.address;
- const spender = bob.address;
- const value = 1e6;
- const validAfter = 0;
- const validBefore = MAX_UINT256;
-
- // create a signed authorization
- const authorization = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // create cancellation
- const cancellation = signCancelAuthorization(
- owner,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(0);
-
- // cancel the authorization
- await fiatToken.cancelAuthorization(
- owner,
- nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
- { from: charlie }
- );
-
- // check that the authorization state is now 2 = Canceled
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(2);
-
- // attempt to use the canceled authorization
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- authorization.v,
- authorization.r,
- authorization.s,
+ ...prepareSignature(authorization, signatureBytesType),
{ from: charlie }
),
"authorization is used or canceled"
@@ -302,11 +139,10 @@ export function testCancelAuthorization({
});
it("cannot be used to cancel someone else's authorization", async () => {
- const from = alice.address;
const to = bob.address;
const value = 7e6;
const validAfter = 0;
- const validBefore = MAX_UINT256;
+ const validBefore = MAX_UINT256_HEX;
// create a signed authorization
const authorization = signTransferAuthorization(
@@ -320,10 +156,8 @@ export function testCancelAuthorization({
alice.key
);
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(0);
+ // check that the authorization state is false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
// create cancellation
const cancellation = signCancelAuthorization(
@@ -338,18 +172,14 @@ export function testCancelAuthorization({
fiatToken.cancelAuthorization(
from,
nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
+ ...prepareSignature(cancellation, signatureBytesType),
{ from: charlie }
),
"invalid signature"
);
- // check that the authorization state is still 0 = Unused
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(0);
+ // check that the authorization state is still false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
// authorization should not have been canceled
await fiatToken.transferWithAuthorization(
@@ -359,19 +189,16 @@ export function testCancelAuthorization({
validAfter,
validBefore,
nonce,
- authorization.v,
- authorization.r,
- authorization.s,
+ ...prepareSignature(authorization, signatureBytesType),
{ from: charlie }
);
});
it("reverts if the authorization has already been used", async () => {
- const from = alice.address;
const to = bob.address;
const value = 7e6;
const validAfter = 0;
- const validBefore = MAX_UINT256;
+ const validBefore = MAX_UINT256_HEX;
// create a signed authorization
const authorization = signTransferAuthorization(
@@ -393,9 +220,7 @@ export function testCancelAuthorization({
validAfter,
validBefore,
nonce,
- authorization.v,
- authorization.r,
- authorization.s,
+ ...prepareSignature(authorization, signatureBytesType),
{ from: charlie }
);
@@ -412,9 +237,7 @@ export function testCancelAuthorization({
fiatToken.cancelAuthorization(
from,
nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
+ ...prepareSignature(cancellation, signatureBytesType),
{ from: charlie }
),
"authorization is used or canceled"
@@ -424,7 +247,7 @@ export function testCancelAuthorization({
it("reverts if the authorization has already been canceled", async () => {
// create cancellation
const cancellation = signCancelAuthorization(
- alice.address,
+ from,
nonce,
domainSeparator,
alice.key
@@ -432,22 +255,18 @@ export function testCancelAuthorization({
// submit the cancellation
await fiatToken.cancelAuthorization(
- alice.address,
+ from,
nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
+ ...prepareSignature(cancellation, signatureBytesType),
{ from: charlie }
);
// try to submit the same cancellation again
await expectRevert(
fiatToken.cancelAuthorization(
- alice.address,
+ from,
nonce,
- cancellation.v,
- cancellation.r,
- cancellation.s,
+ ...prepareSignature(cancellation, signatureBytesType),
{ from: charlie }
),
"authorization is used or canceled"
@@ -456,8 +275,8 @@ export function testCancelAuthorization({
it("reverts if the contract is paused", async () => {
// create a cancellation
- const { v, r, s } = signCancelAuthorization(
- alice.address,
+ const cancellation = signCancelAuthorization(
+ from,
nonce,
domainSeparator,
alice.key
@@ -468,9 +287,15 @@ export function testCancelAuthorization({
// try to submit the cancellation
await expectRevert(
- fiatToken.cancelAuthorization(alice.address, nonce, v, r, s, {
- from: charlie,
- }),
+ fiatToken.cancelAuthorization(
+ from,
+ nonce,
+ ...prepareSignature(cancellation, signatureBytesType),
+
+ {
+ from: charlie,
+ }
+ ),
"paused"
);
});
diff --git a/test/v2/GasAbstraction/testDecreaseAllowanceWithAuthorization.ts b/test/v2/GasAbstraction/testDecreaseAllowanceWithAuthorization.ts
deleted file mode 100644
index b4989342d..000000000
--- a/test/v2/GasAbstraction/testDecreaseAllowanceWithAuthorization.ts
+++ /dev/null
@@ -1,725 +0,0 @@
-import crypto from "crypto";
-import { FiatTokenV2Instance } from "../../../@types/generated";
-import {
- AuthorizationUsed,
- Approval,
-} from "../../../@types/generated/FiatTokenV2";
-import {
- ACCOUNTS_AND_KEYS,
- MAX_UINT256,
- ZERO_ADDRESS,
-} from "../../helpers/constants";
-import { expectRevert, hexStringFromBuffer } from "../../helpers";
-import {
- decreaseAllowanceWithAuthorizationTypeHash,
- signIncreaseAllowanceAuthorization,
- signDecreaseAllowanceAuthorization,
- signTransferAuthorization,
- TestParams,
-} from "./helpers";
-
-export function testDecreaseAllowanceWithAuthorization({
- getFiatToken,
- getDomainSeparator,
- fiatTokenOwner,
- accounts,
-}: TestParams): void {
- describe("decreaseAllowanceWithAuthorization", () => {
- let fiatToken: FiatTokenV2Instance;
- let domainSeparator: string;
- const [alice, bob] = ACCOUNTS_AND_KEYS;
- const charlie = accounts[1];
- let nonce: string;
-
- const initialBalance = 10e6;
- const initialAllowance = 10e6;
- const decreaseAllowanceParams = {
- owner: alice.address,
- spender: bob.address,
- decrement: 3e6,
- validAfter: 0,
- validBefore: MAX_UINT256,
- };
-
- beforeEach(async () => {
- fiatToken = getFiatToken();
- domainSeparator = getDomainSeparator();
- nonce = hexStringFromBuffer(crypto.randomBytes(32));
-
- const { owner, spender } = decreaseAllowanceParams;
- await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
- from: fiatTokenOwner,
- });
- await fiatToken.mint(owner, initialBalance, {
- from: fiatTokenOwner,
- });
-
- // set initial allowance to be 10e6
- const nonceForIncrease = hexStringFromBuffer(crypto.randomBytes(32));
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- initialAllowance,
- 0,
- MAX_UINT256,
- nonceForIncrease,
- domainSeparator,
- alice.key
- );
-
- await fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- initialAllowance,
- 0,
- MAX_UINT256,
- nonceForIncrease,
- v,
- r,
- s,
- { from: charlie }
- );
- });
-
- it("has the expected type hash", async () => {
- expect(
- await fiatToken.DECREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH()
- ).to.equal(decreaseAllowanceWithAuthorizationTypeHash);
- });
-
- it("decreases allowance by a given amount when a valid authorization is given", async () => {
- const {
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization to decrease the allowance granted to Bob
- // to spend Alice's funds on behalf, and sign with Alice's key
- let { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // check the initial allowance
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- initialAllowance
- );
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(0);
-
- // a third-party, Charlie (not Alice) submits the authorization
- let result = await fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // check that the allowance is decreased
- let newAllowance = initialAllowance - decrement;
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- newAllowance
- );
-
- // check that AuthorizationUsed event is emitted
- let log0 = result.logs[0] as Truffle.TransactionLog;
- expect(log0.event).to.equal("AuthorizationUsed");
- expect(log0.args[0]).to.equal(owner);
- expect(log0.args[1]).to.equal(nonce);
-
- // check that Approval event is emitted
- let log1 = result.logs[1] as Truffle.TransactionLog;
- expect(log1.event).to.equal("Approval");
- expect(log1.args[0]).to.equal(owner);
- expect(log1.args[1]).to.equal(spender);
- expect(log1.args[2].toNumber()).to.equal(newAllowance);
-
- // check that the authorization state is now 1 = Used
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(1);
-
- // create another signed authorization to decrease the allowance by
- // another 2e6
- const decrement2 = 2e6;
- const nonce2 = hexStringFromBuffer(crypto.randomBytes(32));
- ({ v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement2,
- validAfter,
- validBefore,
- nonce2,
- domainSeparator,
- alice.key
- ));
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce2)).toNumber()
- ).to.equal(0);
-
- // submit the second authorization
- result = await fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement2,
- validAfter,
- validBefore,
- nonce2,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // check that the allowance is decreased
- newAllowance -= decrement2;
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- newAllowance
- );
-
- // check that AuthorizationUsed event is emitted
- log0 = result.logs[0] as Truffle.TransactionLog;
- expect(log0.event).to.equal("AuthorizationUsed");
- expect(log0.args[0]).to.equal(owner);
- expect(log0.args[1]).to.equal(nonce2);
-
- // check that Approval event is emitted
- log1 = result.logs[1] as Truffle.TransactionLog;
- expect(log1.event).to.equal("Approval");
- expect(log1.args[0]).to.equal(owner);
- expect(log1.args[1]).to.equal(spender);
- expect(log1.args[2].toNumber()).to.equal(newAllowance);
-
- // check that the authorization state is now 1 = Used
- expect(
- (await fiatToken.authorizationState(owner, nonce2)).toNumber()
- ).to.equal(1);
- });
-
- it("reverts if the decrease is greater than current allowance", async () => {
- const {
- owner,
- spender,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- const decrement = initialAllowance + 1;
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization with invalid approval parameters
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "decreased allowance below zero"
- );
- });
-
- it("reverts if the decrease causes an integer overflow", async () => {
- const {
- owner,
- spender,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- const decrement = MAX_UINT256;
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // a subtraction causing overflow does not actually happen because
- // it catches that the given decrement is greater than the current
- // allowance
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "decreased allowance below zero"
- );
- });
-
- it("reverts if the signature does not match given parameters", async () => {
- const {
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to cheat by claiming the decrease is double
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement * 2, // pass incorrect value
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the signature is not signed with the right key", async () => {
- const {
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization to decrease the allowance granted to Bob
- // to spend Alice's funds on behalf, but sign with Bob's key instead of
- // Alice's
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- bob.key
- );
-
- // try to cheat by submitting the authorization that is signed by a
- // wrong person
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the authorization is not yet valid", async () => {
- const {
- owner,
- spender,
- decrement,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization that won't be valid until 10 seconds
- // later
- const validAfter = Math.floor(Date.now() / 1000) + 10;
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization early
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is not yet valid"
- );
- });
-
- it("reverts if the authorization is expired", async () => {
- const { owner, spender, decrement, validAfter } = decreaseAllowanceParams;
- // create a signed authorization that won't be valid until 10 seconds
- // later
- const validBefore = Math.floor(Date.now() / 1000);
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization that is expired
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is expired"
- );
- });
-
- it("reverts if the authorization has already been used", async () => {
- const {
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // submit the authorization
- await fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // try to submit the authorization again
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("reverts if the authorization has a nonce that has already been used by the signer", async () => {
- const {
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization
- const authorization = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // submit the authorization
- await fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- authorization.v,
- authorization.r,
- authorization.s,
- { from: charlie }
- );
-
- // create another signed authorization with the same nonce, but
- // with different parameters
- const authorization2 = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- 1e6,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization again
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- 1e6,
- validAfter,
- validBefore,
- nonce,
- authorization2.v,
- authorization2.r,
- authorization2.s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("reverts if the authorization includes invalid parameters", async () => {
- const { owner, validAfter, validBefore } = decreaseAllowanceParams;
- const decrement = 0;
- // create a signed authorization that attempts to grant allowance to the
- // zero address
- const spender = ZERO_ADDRESS;
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization with invalid approval parameters
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "approve to the zero address"
- );
- });
-
- it("reverts if the authorization is not for an decrease in allowance", async () => {
- const {
- owner: from,
- spender: to,
- decrement: value,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization for a transfer
- const { v, r, s } = signTransferAuthorization(
- from,
- to,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the transfer authorization
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- from,
- to,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the contract is paused", async () => {
- const {
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // pause the contract
- await fiatToken.pause({ from: fiatTokenOwner });
-
- // try to submit the authorization
- await expectRevert(
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "paused"
- );
- });
-
- it("reverts if the owner or the spender is blacklisted", async () => {
- const {
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- } = decreaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signDecreaseAllowanceAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // owner is blacklisted
- await fiatToken.blacklist(owner, { from: fiatTokenOwner });
-
- const submitTx = () =>
- fiatToken.decreaseAllowanceWithAuthorization(
- owner,
- spender,
- decrement,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // try to submit the authorization
- await expectRevert(submitTx(), "account is blacklisted");
-
- // spender is blacklisted
- await fiatToken.unBlacklist(owner, { from: fiatTokenOwner });
- await fiatToken.blacklist(spender, { from: fiatTokenOwner });
-
- // try to submit the authorization
- await expectRevert(submitTx(), "account is blacklisted");
- });
- });
-}
diff --git a/test/v2/GasAbstraction/testIncreaseAllowanceWithAuthorization.ts b/test/v2/GasAbstraction/testIncreaseAllowanceWithAuthorization.ts
deleted file mode 100644
index 4fa9aa46c..000000000
--- a/test/v2/GasAbstraction/testIncreaseAllowanceWithAuthorization.ts
+++ /dev/null
@@ -1,683 +0,0 @@
-import crypto from "crypto";
-import { FiatTokenV2Instance } from "../../../@types/generated";
-import {
- AuthorizationUsed,
- Approval,
-} from "../../../@types/generated/FiatTokenV2";
-import {
- ACCOUNTS_AND_KEYS,
- MAX_UINT256,
- ZERO_ADDRESS,
-} from "../../helpers/constants";
-import { expectRevert, hexStringFromBuffer } from "../../helpers";
-import {
- increaseAllowanceWithAuthorizationTypeHash,
- signIncreaseAllowanceAuthorization,
- signTransferAuthorization,
- TestParams,
-} from "./helpers";
-
-export function testIncreaseAllowanceWithAuthorization({
- getFiatToken,
- getDomainSeparator,
- fiatTokenOwner,
- accounts,
-}: TestParams): void {
- describe("increaseAllowanceWithAuthorization", () => {
- let fiatToken: FiatTokenV2Instance;
- let domainSeparator: string;
- const [alice, bob] = ACCOUNTS_AND_KEYS;
- const charlie = accounts[1];
- let nonce: string;
-
- const initialBalance = 10e6;
- const increaseAllowanceParams = {
- owner: alice.address,
- spender: bob.address,
- increment: 3e6,
- validAfter: 0,
- validBefore: MAX_UINT256,
- };
-
- beforeEach(async () => {
- fiatToken = getFiatToken();
- domainSeparator = getDomainSeparator();
- nonce = hexStringFromBuffer(crypto.randomBytes(32));
- await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
- from: fiatTokenOwner,
- });
- await fiatToken.mint(increaseAllowanceParams.owner, initialBalance, {
- from: fiatTokenOwner,
- });
- });
-
- it("has the expected type hash", async () => {
- expect(
- await fiatToken.INCREASE_ALLOWANCE_WITH_AUTHORIZATION_TYPEHASH()
- ).to.equal(increaseAllowanceWithAuthorizationTypeHash);
- });
-
- it("increases allowance by a given amount when a valid authorization is given", async () => {
- const {
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization to increase the allowance granted to Bob
- // to spend Alice's funds on behalf, and sign with Alice's key
- let { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // check that the allowance is initially zero
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- 0
- );
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce)).toNumber()
- ).to.equal(0);
-
- // a third-party, Charlie (not Alice) submits the authorization
- let result = await fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // check that the allowance is increased
- let newAllowance = increment;
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- newAllowance
- );
-
- // check that AuthorizationUsed event is emitted
- let log0 = result.logs[0] as Truffle.TransactionLog;
- expect(log0.event).to.equal("AuthorizationUsed");
- expect(log0.args[0]).to.equal(owner);
- expect(log0.args[1]).to.equal(nonce);
-
- // check that Approval event is emitted
- let log1 = result.logs[1] as Truffle.TransactionLog;
- expect(log1.event).to.equal("Approval");
- expect(log1.args[0]).to.equal(owner);
- expect(log1.args[1]).to.equal(spender);
- expect(log1.args[2].toNumber()).to.equal(newAllowance);
-
- // create another signed authorization to increase the allowance by
- // another 2e6
- const increment2 = 2e6;
- const nonce2 = hexStringFromBuffer(crypto.randomBytes(32));
- ({ v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment2,
- validAfter,
- validBefore,
- nonce2,
- domainSeparator,
- alice.key
- ));
-
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(owner, nonce2)).toNumber()
- ).to.equal(0);
-
- // submit the second authorization
- result = await fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment2,
- validAfter,
- validBefore,
- nonce2,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // check that the allowance is increased
- newAllowance += increment2;
- expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
- newAllowance
- );
-
- // check that AuthorizationUsed event is emitted
- log0 = result.logs[0] as Truffle.TransactionLog;
- expect(log0.event).to.equal("AuthorizationUsed");
- expect(log0.args[0]).to.equal(owner);
- expect(log0.args[1]).to.equal(nonce2);
-
- // check that Approval event is emitted
- log1 = result.logs[1] as Truffle.TransactionLog;
- expect(log1.event).to.equal("Approval");
- expect(log1.args[0]).to.equal(owner);
- expect(log1.args[1]).to.equal(spender);
- expect(log1.args[2].toNumber()).to.equal(newAllowance);
-
- // check that the authorization state is now 1 = Used
- expect(
- (await fiatToken.authorizationState(owner, nonce2)).toNumber()
- ).to.equal(1);
- });
-
- it("reverts if the decrease causes an integer overflow", async () => {
- const {
- owner,
- spender,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
-
- // set initial allowance of 1
- let { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- 1,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- await fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- 1,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // try to increase by max uint256 which will trigger addition overflow
- const increment = MAX_UINT256;
- nonce = hexStringFromBuffer(crypto.randomBytes(32));
- ({ v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- ));
-
- // submit the authorization causing overflow
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "addition overflow"
- );
- });
-
- it("reverts if the signature does not match given parameters", async () => {
- const {
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to cheat by claiming the increase is double
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment * 2, // pass incorrect value
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the signature is not signed with the right key", async () => {
- const {
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization to increase the allowance granted to Bob
- // to spend Alice's funds on behalf, but sign with Bob's key instead of
- // Alice's
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- bob.key
- );
-
- // try to cheat by submitting the authorization that is signed by a
- // wrong person
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the authorization is not yet valid", async () => {
- const {
- owner,
- spender,
- increment,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization that won't be valid until 10 seconds
- // later
- const validAfter = Math.floor(Date.now() / 1000) + 10;
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization early
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is not yet valid"
- );
- });
-
- it("reverts if the authorization is expired", async () => {
- const { owner, spender, increment, validAfter } = increaseAllowanceParams;
- // create a signed authorization that won't be valid until 10 seconds
- // later
- const validBefore = Math.floor(Date.now() / 1000);
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization that is expired
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is expired"
- );
- });
-
- it("reverts if the authorization has already been used", async () => {
- const {
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // submit the authorization
- await fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // try to submit the authorization again
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("reverts if the authorization has a nonce that has already been used by the signer", async () => {
- const {
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization
- const authorization = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // submit the authorization
- await fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- authorization.v,
- authorization.r,
- authorization.s,
- { from: charlie }
- );
-
- // create another signed authorization with the same nonce, but
- // with different parameters
- const authorization2 = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- 1e6,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization again
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- 1e6,
- validAfter,
- validBefore,
- nonce,
- authorization2.v,
- authorization2.r,
- authorization2.s,
- { from: charlie }
- ),
- "authorization is used or canceled"
- );
- });
-
- it("reverts if the authorization includes invalid parameters", async () => {
- const {
- owner,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization that attempts to grant allowance to the
- // zero address
- const spender = ZERO_ADDRESS;
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the authorization with invalid approval parameters
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "approve to the zero address"
- );
- });
-
- it("reverts if the authorization is not for an increase in allowance", async () => {
- const {
- owner: from,
- spender: to,
- increment: value,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization for a transfer
- const { v, r, s } = signTransferAuthorization(
- from,
- to,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the transfer authorization
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- from,
- to,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
- it("reverts if the contract is paused", async () => {
- const {
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // pause the contract
- await fiatToken.pause({ from: fiatTokenOwner });
-
- // try to submit the authorization
- await expectRevert(
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "paused"
- );
- });
-
- it("reverts if the owner or the spender is blacklisted", async () => {
- const {
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- } = increaseAllowanceParams;
- // create a signed authorization
- const { v, r, s } = signIncreaseAllowanceAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // owner is blacklisted
- await fiatToken.blacklist(owner, { from: fiatTokenOwner });
-
- const submitTx = () =>
- fiatToken.increaseAllowanceWithAuthorization(
- owner,
- spender,
- increment,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- );
-
- // try to submit the authorization
- await expectRevert(submitTx(), "account is blacklisted");
-
- // spender is blacklisted
- await fiatToken.unBlacklist(owner, { from: fiatTokenOwner });
- await fiatToken.blacklist(spender, { from: fiatTokenOwner });
-
- // try to submit the authorization
- await expectRevert(submitTx(), "account is blacklisted");
- });
- });
-}
diff --git a/test/v2/GasAbstraction/testPermit.ts b/test/v2/GasAbstraction/testPermit.ts
index 420b746ba..1b4d03315 100644
--- a/test/v2/GasAbstraction/testPermit.ts
+++ b/test/v2/GasAbstraction/testPermit.ts
@@ -1,9 +1,28 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import crypto from "crypto";
-import { FiatTokenV2Instance } from "../../../@types/generated";
+import { MockERC1271WalletInstance } from "../../../@types/generated";
import { Approval } from "../../../@types/generated/FiatTokenV2";
import {
ACCOUNTS_AND_KEYS,
- MAX_UINT256,
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_HEX,
ZERO_ADDRESS,
} from "../../helpers/constants";
import { expectRevert, hexStringFromBuffer } from "../../helpers";
@@ -12,32 +31,53 @@ import {
TestParams,
signTransferAuthorization,
permitTypeHash,
+ WalletType,
+ prepareSignature,
} from "./helpers";
+import { AnyFiatTokenV2Instance } from "../../../@types/AnyFiatTokenV2Instance";
export function testPermit({
+ version,
getFiatToken,
+ getERC1271Wallet,
getDomainSeparator,
- fiatTokenOwner,
- accounts,
+ signerWalletType,
+ signatureBytesType,
}: TestParams): void {
- describe("permit", () => {
- let fiatToken: FiatTokenV2Instance;
- let domainSeparator: string;
+ describe(`permit with ${signerWalletType} wallet, ${signatureBytesType} signature interface`, async () => {
const [alice, bob] = ACCOUNTS_AND_KEYS;
- const charlie = accounts[1];
+ const charlie = HARDHAT_ACCOUNTS[1];
const initialBalance = 10e6;
const permitParams = {
- owner: alice.address,
+ owner: "",
spender: bob.address,
value: 7e6,
nonce: 0,
- deadline: MAX_UINT256,
+ deadline: Math.floor(Date.now() / 1000) + 60 * 60 * 24,
};
+ let fiatTokenOwner: string;
+ let fiatToken: AnyFiatTokenV2Instance;
+ let aliceWallet: MockERC1271WalletInstance;
+ let domainSeparator: string;
+
+ before(async () => {
+ fiatTokenOwner = await getFiatToken().owner();
+ });
+
beforeEach(async () => {
fiatToken = getFiatToken();
+ aliceWallet = await getERC1271Wallet(alice.address);
domainSeparator = getDomainSeparator();
+
+ // Initialize `owner` address either as Alice's EOA address or Alice's wallet address
+ if (signerWalletType == WalletType.AA) {
+ permitParams.owner = aliceWallet.address;
+ } else {
+ permitParams.owner = alice.address;
+ }
+
await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
from: fiatTokenOwner,
});
@@ -56,7 +96,7 @@ export function testPermit({
// create a signed permit to grant Bob permission to spend Alice's funds
// on behalf, and sign with Alice's key
let nonce = 0;
- let { v, r, s } = signPermit(
+ const signature1 = signPermit(
owner,
spender,
value,
@@ -79,9 +119,7 @@ export function testPermit({
spender,
value,
deadline,
- v,
- r,
- s,
+ ...prepareSignature(signature1, signatureBytesType),
{ from: charlie }
);
@@ -103,7 +141,7 @@ export function testPermit({
// increment nonce
nonce = 1;
value = 1e6;
- ({ v, r, s } = signPermit(
+ const signature2 = signPermit(
owner,
spender,
1e6,
@@ -111,7 +149,7 @@ export function testPermit({
deadline,
domainSeparator,
alice.key
- ));
+ );
// submit the permit
result = await fiatToken.permit(
@@ -119,9 +157,7 @@ export function testPermit({
spender,
value,
deadline,
- v,
- r,
- s,
+ ...prepareSignature(signature2, signatureBytesType),
{ from: charlie }
);
@@ -138,10 +174,54 @@ export function testPermit({
expect(log.args[2].toNumber()).to.equal(1e6);
});
+ it("grants allowance when a valid permit is given with (2^256 - 1) as deadline", async () => {
+ const { owner, spender, value, nonce } = permitParams;
+ const deadline = MAX_UINT256_HEX;
+
+ const signature = signPermit(
+ owner,
+ spender,
+ value,
+ nonce,
+ deadline,
+ domainSeparator,
+ alice.key
+ );
+
+ // check that the allowance is initially zero
+ expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
+ 0
+ );
+ // check that the next nonce expected is zero
+ expect((await fiatToken.nonces(owner)).toNumber()).to.equal(0);
+
+ // a third-party, Charlie (not Alice) submits the permit
+ const result = await fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: charlie }
+ );
+
+ // check that allowance is updated
+ expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
+ value
+ );
+
+ // check that Approval event is emitted
+ const log = result.logs[0] as Truffle.TransactionLog;
+ expect(log.event).to.equal("Approval");
+ expect(log.args[0]).to.equal(owner);
+ expect(log.args[1]).to.equal(spender);
+ expect(log.args[2].toNumber()).to.equal(value);
+ });
+
it("reverts if the signature does not match given parameters", async () => {
const { owner, spender, value, nonce, deadline } = permitParams;
// create a signed permit
- const { v, r, s } = signPermit(
+ const signature = signPermit(
owner,
spender,
value,
@@ -158,9 +238,7 @@ export function testPermit({
spender,
value * 2, // pass incorrect value
deadline,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"invalid signature"
@@ -171,7 +249,7 @@ export function testPermit({
const { owner, spender, value, nonce, deadline } = permitParams;
// create a signed permit to grant Bob permission to spend
// Alice's funds on behalf, but sign with Bob's key instead of Alice's
- const { v, r, s } = signPermit(
+ const signature = signPermit(
owner,
spender,
value,
@@ -184,9 +262,16 @@ export function testPermit({
// try to cheat by submitting the permit that is signed by a
// wrong person
await expectRevert(
- fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- }),
+ fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ ),
"invalid signature"
);
});
@@ -196,7 +281,7 @@ export function testPermit({
// create a signed permit that won't be valid until 10 seconds
// later
const deadline = Math.floor(Date.now() / 1000) - 1;
- const { v, r, s } = signPermit(
+ const signature = signPermit(
owner,
spender,
value,
@@ -208,9 +293,16 @@ export function testPermit({
// try to submit the permit that is expired
await expectRevert(
- fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- }),
+ fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ ),
"permit is expired"
);
});
@@ -219,7 +311,7 @@ export function testPermit({
const { owner, spender, value, deadline } = permitParams;
const nonce = 1;
// create a signed permit
- const { v, r, s } = signPermit(
+ const signature = signPermit(
owner,
spender,
value,
@@ -233,9 +325,16 @@ export function testPermit({
// try to submit the permit
await expectRevert(
- fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- }),
+ fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ ),
"invalid signature"
);
});
@@ -243,7 +342,7 @@ export function testPermit({
it("reverts if the permit has already been used", async () => {
const { owner, spender, value, nonce, deadline } = permitParams;
// create a signed permit
- const { v, r, s } = signPermit(
+ const signature = signPermit(
owner,
spender,
value,
@@ -254,15 +353,29 @@ export function testPermit({
);
// submit the permit
- await fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- });
+ await fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ );
// try to submit the permit again
await expectRevert(
- fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- }),
+ fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ ),
"invalid signature"
);
});
@@ -286,9 +399,7 @@ export function testPermit({
spender,
value,
deadline,
- permit.v,
- permit.r,
- permit.s,
+ ...prepareSignature(permit, signatureBytesType),
{ from: charlie }
);
@@ -311,9 +422,7 @@ export function testPermit({
spender,
1e6,
deadline,
- permit2.v,
- permit2.r,
- permit2.s,
+ ...prepareSignature(permit2, signatureBytesType),
{ from: charlie }
),
"invalid signature"
@@ -325,7 +434,7 @@ export function testPermit({
// create a signed permit that attempts to grant allowance to the
// zero address
const spender = ZERO_ADDRESS;
- const { v, r, s } = signPermit(
+ const signature = signPermit(
owner,
spender,
value,
@@ -337,9 +446,16 @@ export function testPermit({
// try to submit the permit with invalid approval parameters
await expectRevert(
- fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- }),
+ fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ ),
"approve to the zero address"
);
});
@@ -354,7 +470,7 @@ export function testPermit({
// create a signed permit for a transfer
const validAfter = 0;
const nonce = hexStringFromBuffer(crypto.randomBytes(32));
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -367,9 +483,16 @@ export function testPermit({
// try to submit the transfer permit
await expectRevert(
- fiatToken.permit(from, to, value, validBefore, v, r, s, {
- from: charlie,
- }),
+ fiatToken.permit(
+ from,
+ to,
+ value,
+ validBefore,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ ),
"invalid signature"
);
});
@@ -377,7 +500,7 @@ export function testPermit({
it("reverts if the contract is paused", async () => {
const { owner, spender, value, nonce, deadline } = permitParams;
// create a signed permit
- const { v, r, s } = signPermit(
+ const signature = signPermit(
owner,
spender,
value,
@@ -392,43 +515,106 @@ export function testPermit({
// try to submit the permit
await expectRevert(
- fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- }),
+ fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: charlie }
+ ),
"paused"
);
});
- it("reverts if the owner or the spender is blacklisted", async () => {
- const { owner, spender, value, nonce, deadline } = permitParams;
- // create a signed permit
- const { v, r, s } = signPermit(
- owner,
- spender,
- value,
- nonce,
- deadline,
- domainSeparator,
- alice.key
- );
-
- // owner is blacklisted
- await fiatToken.blacklist(owner, { from: fiatTokenOwner });
-
- const submitTx = () =>
- fiatToken.permit(owner, spender, value, deadline, v, r, s, {
- from: charlie,
- });
-
- // try to submit the permit
- await expectRevert(submitTx(), "account is blacklisted");
-
- // spender is blacklisted
- await fiatToken.unBlacklist(owner, { from: fiatTokenOwner });
- await fiatToken.blacklist(spender, { from: fiatTokenOwner });
-
- // try to submit the permit
- await expectRevert(submitTx(), "account is blacklisted");
- });
+ if (version < 2.2) {
+ it("reverts if the owner or the spender is blacklisted", async () => {
+ const { owner, spender, value, nonce, deadline } = permitParams;
+ // create a signed permit
+ const signature = signPermit(
+ owner,
+ spender,
+ value,
+ nonce,
+ deadline,
+ domainSeparator,
+ alice.key
+ );
+
+ // owner is blacklisted
+ await fiatToken.blacklist(owner, { from: fiatTokenOwner });
+
+ const submitTx = () =>
+ fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ );
+
+ // try to submit the permit
+ await expectRevert(submitTx(), "account is blacklisted");
+
+ // spender is blacklisted
+ await fiatToken.unBlacklist(owner, { from: fiatTokenOwner });
+ await fiatToken.blacklist(spender, { from: fiatTokenOwner });
+
+ // try to submit the permit
+ await expectRevert(submitTx(), "account is blacklisted");
+ });
+ } else {
+ // version >= 2.2
+
+ it("grants allowance normally when the owner or the spender is blacklisted", async () => {
+ const { owner, spender, value, deadline } = permitParams;
+
+ const submitTxWithNonce = (nonce: number, value: number) => {
+ const signature = signPermit(
+ owner,
+ spender,
+ value,
+ nonce,
+ deadline,
+ domainSeparator,
+ alice.key
+ );
+ return fiatToken.permit(
+ owner,
+ spender,
+ value,
+ deadline,
+ ...prepareSignature(signature, signatureBytesType),
+ {
+ from: charlie,
+ }
+ );
+ };
+
+ // owner is blacklisted
+ await fiatToken.blacklist(owner, { from: fiatTokenOwner });
+
+ // try to submit the permit
+ await submitTxWithNonce(0, value);
+ // check that allowance is updated
+ expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
+ value
+ );
+
+ // spender is blacklisted
+ await fiatToken.unBlacklist(owner, { from: fiatTokenOwner });
+ await fiatToken.blacklist(spender, { from: fiatTokenOwner });
+
+ // try to submit the permit
+ await submitTxWithNonce(1, value * 2);
+ // check that allowance is updated
+ expect((await fiatToken.allowance(owner, spender)).toNumber()).to.equal(
+ value * 2
+ );
+ });
+ }
});
}
diff --git a/test/v2/GasAbstraction/testReceiveWithAuthorization.ts b/test/v2/GasAbstraction/testReceiveWithAuthorization.ts
new file mode 100644
index 000000000..e2c584d25
--- /dev/null
+++ b/test/v2/GasAbstraction/testReceiveWithAuthorization.ts
@@ -0,0 +1,510 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import crypto from "crypto";
+import { MockERC1271WalletInstance } from "../../../@types/generated";
+import {
+ AuthorizationUsed,
+ Transfer,
+} from "../../../@types/generated/FiatTokenV2";
+import {
+ ACCOUNTS_AND_KEYS,
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_HEX,
+} from "../../helpers/constants";
+import { expectRevert, hexStringFromBuffer } from "../../helpers";
+import {
+ prepareSignature,
+ receiveWithAuthorizationTypeHash,
+ signReceiveAuthorization,
+ TestParams,
+ WalletType,
+} from "./helpers";
+import { AnyFiatTokenV2Instance } from "../../../@types/AnyFiatTokenV2Instance";
+
+export function testReceiveWithAuthorization({
+ getFiatToken,
+ getERC1271Wallet,
+ getDomainSeparator,
+ signerWalletType,
+ signatureBytesType,
+}: TestParams): void {
+ describe(`receiveWithAuthorization with ${signerWalletType} wallet, ${signatureBytesType} signature interface`, async () => {
+ const [alice, charlie] = ACCOUNTS_AND_KEYS;
+ const [, bob, david] = HARDHAT_ACCOUNTS;
+ const nonce: string = hexStringFromBuffer(crypto.randomBytes(32));
+ const initialBalance = 10e6;
+ const receiveParams = {
+ from: "",
+ to: bob,
+ value: 7e6,
+ validAfter: 0,
+ validBefore: MAX_UINT256_HEX,
+ nonce,
+ };
+
+ let fiatTokenOwner: string;
+ let fiatToken: AnyFiatTokenV2Instance;
+ let aliceWallet: MockERC1271WalletInstance;
+ let domainSeparator: string;
+
+ before(async () => {
+ fiatTokenOwner = await getFiatToken().owner();
+ });
+
+ beforeEach(async () => {
+ fiatToken = getFiatToken();
+ aliceWallet = await getERC1271Wallet(alice.address);
+ domainSeparator = getDomainSeparator();
+
+ // Initialize `from` address either as Alice's EOA address or Alice's wallet address
+ if (signerWalletType == WalletType.AA) {
+ receiveParams.from = aliceWallet.address;
+ } else {
+ receiveParams.from = alice.address;
+ }
+
+ await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
+ from: fiatTokenOwner,
+ });
+ await fiatToken.mint(receiveParams.from, initialBalance, {
+ from: fiatTokenOwner,
+ });
+ });
+
+ it("has the expected type hash", async () => {
+ expect(await fiatToken.RECEIVE_WITH_AUTHORIZATION_TYPEHASH()).to.equal(
+ receiveWithAuthorizationTypeHash
+ );
+ });
+
+ it("executes a transfer when a valid authorization is given and the caller is the payee", async () => {
+ const { from, to, value, validAfter, validBefore } = receiveParams;
+ // create an authorization to transfer money from Alice to Bob and sign
+ // with Alice's key
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // check initial balance
+ expect((await fiatToken.balanceOf(from)).toNumber()).to.equal(10e6);
+ expect((await fiatToken.balanceOf(to)).toNumber()).to.equal(0);
+
+ // check that the authorization state is false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
+
+ // The recipient (Bob) submits the signed authorization
+ const result = await fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ );
+
+ // check that balance is updated
+ expect((await fiatToken.balanceOf(from)).toNumber()).to.equal(
+ initialBalance - value
+ );
+ expect((await fiatToken.balanceOf(to)).toNumber()).to.equal(value);
+
+ // check that AuthorizationUsed event is emitted
+ const log0 = result.logs[0] as Truffle.TransactionLog;
+ expect(log0.event).to.equal("AuthorizationUsed");
+ expect(log0.args[0]).to.equal(from);
+ expect(log0.args[1]).to.equal(nonce);
+
+ // check that Transfer event is emitted
+ const log1 = result.logs[1] as Truffle.TransactionLog;
+ expect(log1.event).to.equal("Transfer");
+ expect(log1.args[0]).to.equal(from);
+ expect(log1.args[1]).to.equal(to);
+ expect(log1.args[2].toNumber()).to.equal(value);
+
+ // check that the authorization state is now true
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(true);
+ });
+
+ it("reverts if the caller is not the payee", async () => {
+ const { from, to, value, validAfter, validBefore } = receiveParams;
+ // create a signed authorization
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // submit the signed authorization from
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: david }
+ ),
+ "caller must be the payee"
+ );
+ });
+
+ it("reverts if the signature does not match given parameters", async () => {
+ const { from, to, value, validAfter, validBefore } = receiveParams;
+ // create a signed authorization
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // try to cheat by claiming the transfer amount is double
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value * 2, // pass incorrect value
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ ),
+ "invalid signature"
+ );
+ });
+
+ it("reverts if the signature is not signed with the right key", async () => {
+ const { from, to, value, validAfter, validBefore } = receiveParams;
+ // create an authorization to transfer money from Alice to Bob, but
+ // sign with Bob's key instead of Alice's
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ charlie.key
+ );
+
+ // try to cheat by submitting the signed authorization that is signed by
+ // a wrong person
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ ),
+ "invalid signature"
+ );
+ });
+
+ it("reverts if the authorization is not yet valid", async () => {
+ const { from, to, value, validBefore } = receiveParams;
+ // create a signed authorization that won't be valid until 1 day later
+ const validAfter = Math.floor(Date.now() / 1000) + 86400;
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // try to submit the authorization early
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ ),
+ "authorization is not yet valid"
+ );
+ });
+
+ it("reverts if the authorization is expired", async () => {
+ // create a signed authorization that expires immediately
+ const { from, to, value, validAfter } = receiveParams;
+ const validBefore = Math.floor(Date.now() / 1000);
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // try to submit the authorization that is expired
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ ),
+ "authorization is expired"
+ );
+ });
+
+ it("reverts if the authorization has already been used", async () => {
+ const { from, to, validAfter, validBefore } = receiveParams;
+ // create a signed authorization
+ const value = 1e6;
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // submit the authorization
+ await fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ );
+
+ // try to submit the authorization again
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ ),
+ "authorization is used or canceled"
+ );
+ });
+
+ it("reverts if the authorization has a nonce that has already been used by the signer", async () => {
+ const { from, to, value, validAfter, validBefore } = receiveParams;
+ // create a signed authorization
+ const authorization = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // submit the authorization
+ await fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(authorization, signatureBytesType),
+ { from: bob }
+ );
+
+ // create another authorization with the same nonce, but with different
+ // parameters
+ const authorization2 = signReceiveAuthorization(
+ from,
+ to,
+ 1e6,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // try to submit the authorization again
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ 1e6,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(authorization2, signatureBytesType),
+ { from: bob }
+ ),
+ "authorization is used or canceled"
+ );
+ });
+
+ it("reverts if the authorization includes invalid transfer parameters", async () => {
+ const { from, to, validAfter, validBefore } = receiveParams;
+ // create a signed authorization that attempts to transfer an amount
+ // that exceeds the sender's balance
+ const value = initialBalance + 1;
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // try to submit the authorization with invalid transfer parameters
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ ),
+ "transfer amount exceeds balance"
+ );
+ });
+
+ it("reverts if the contract is paused", async () => {
+ const { from, to, value, validAfter, validBefore } = receiveParams;
+ // create a signed authorization
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // pause the contract
+ await fiatToken.pause({ from: fiatTokenOwner });
+
+ // try to submit the authorization
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ ),
+ "paused"
+ );
+ });
+
+ it("reverts if the payer or the payee is blacklisted", async () => {
+ const { from, to, value, validAfter, validBefore } = receiveParams;
+ // create a signed authorization
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ alice.key
+ );
+
+ // payer is blacklisted
+ await fiatToken.blacklist(from, { from: fiatTokenOwner });
+
+ const submitTx = () =>
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, signatureBytesType),
+ { from: bob }
+ );
+
+ // try to submit the authorization
+ await expectRevert(submitTx(), "account is blacklisted");
+
+ // payee is blacklisted
+ await fiatToken.unBlacklist(from, { from: fiatTokenOwner });
+ await fiatToken.blacklist(to, { from: fiatTokenOwner });
+
+ // try to submit the authorization
+ await expectRevert(submitTx(), "account is blacklisted");
+ });
+ });
+}
diff --git a/test/v2/GasAbstraction/testTransferWithAuthorization.ts b/test/v2/GasAbstraction/testTransferWithAuthorization.ts
index e86ccb43c..88fed60d6 100644
--- a/test/v2/GasAbstraction/testTransferWithAuthorization.ts
+++ b/test/v2/GasAbstraction/testTransferWithAuthorization.ts
@@ -1,44 +1,84 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import crypto from "crypto";
-import { FiatTokenV2Instance } from "../../../@types/generated";
+import { MockERC1271WalletInstance } from "../../../@types/generated";
import {
AuthorizationUsed,
Transfer,
} from "../../../@types/generated/FiatTokenV2";
-import { ACCOUNTS_AND_KEYS, MAX_UINT256 } from "../../helpers/constants";
+import {
+ ACCOUNTS_AND_KEYS,
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_HEX,
+} from "../../helpers/constants";
import { expectRevert, hexStringFromBuffer } from "../../helpers";
import {
transferWithAuthorizationTypeHash,
signTransferAuthorization,
TestParams,
- signApproveAuthorization,
+ WalletType,
+ prepareSignature,
} from "./helpers";
+import { AnyFiatTokenV2Instance } from "../../../@types/AnyFiatTokenV2Instance";
export function testTransferWithAuthorization({
getFiatToken,
+ getERC1271Wallet,
getDomainSeparator,
- fiatTokenOwner,
- accounts,
+ signerWalletType,
+ signatureBytesType,
}: TestParams): void {
- describe("transferWithAuthorization", () => {
- let fiatToken: FiatTokenV2Instance;
- let domainSeparator: string;
+ describe(`transferWithAuthorization with ${signerWalletType} wallet, ${signatureBytesType} signature interface`, async () => {
const [alice, bob] = ACCOUNTS_AND_KEYS;
- const charlie = accounts[1];
- let nonce: string;
-
+ const charlie = HARDHAT_ACCOUNTS[1];
+ const nonce: string = hexStringFromBuffer(crypto.randomBytes(32));
const initialBalance = 10e6;
const transferParams = {
- from: alice.address,
+ from: "",
to: bob.address,
value: 7e6,
validAfter: 0,
- validBefore: MAX_UINT256,
+ validBefore: MAX_UINT256_HEX,
+ nonce,
};
+ let fiatTokenOwner: string;
+ let fiatToken: AnyFiatTokenV2Instance;
+ let aliceWallet: MockERC1271WalletInstance;
+ let domainSeparator: string;
+
+ before(async () => {
+ fiatTokenOwner = await getFiatToken().owner();
+ });
+
beforeEach(async () => {
fiatToken = getFiatToken();
+ aliceWallet = await getERC1271Wallet(alice.address);
domainSeparator = getDomainSeparator();
- nonce = hexStringFromBuffer(crypto.randomBytes(32));
+
+ // Initialize `from` address either as Alice's EOA address or Alice's wallet address
+ if (signerWalletType == WalletType.AA) {
+ transferParams.from = aliceWallet.address;
+ } else {
+ transferParams.from = alice.address;
+ }
+
await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
from: fiatTokenOwner,
});
@@ -57,7 +97,7 @@ export function testTransferWithAuthorization({
const { from, to, value, validAfter, validBefore } = transferParams;
// create an authorization to transfer money from Alice to Bob and sign
// with Alice's key
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -72,10 +112,8 @@ export function testTransferWithAuthorization({
expect((await fiatToken.balanceOf(from)).toNumber()).to.equal(10e6);
expect((await fiatToken.balanceOf(to)).toNumber()).to.equal(0);
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(0);
+ // check that the authorization state is false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
// a third-party, Charlie (not Alice) submits the signed authorization
const result = await fiatToken.transferWithAuthorization(
@@ -85,9 +123,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
);
@@ -110,16 +146,14 @@ export function testTransferWithAuthorization({
expect(log1.args[1]).to.equal(to);
expect(log1.args[2].toNumber()).to.equal(value);
- // check that the authorization state is now 1 = Used
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(1);
+ // check that the authorization state is now true
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(true);
});
it("reverts if the signature does not match given parameters", async () => {
const { from, to, value, validAfter, validBefore } = transferParams;
// create a signed authorization
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -139,9 +173,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"invalid signature"
@@ -152,7 +184,7 @@ export function testTransferWithAuthorization({
const { from, to, value, validAfter, validBefore } = transferParams;
// create an authorization to transfer money from Alice to Bob, but
// sign with Bob's key instead of Alice's
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -173,9 +205,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"invalid signature"
@@ -184,10 +214,9 @@ export function testTransferWithAuthorization({
it("reverts if the authorization is not yet valid", async () => {
const { from, to, value, validBefore } = transferParams;
- // create a signed authorization that won't be valid until 10 seconds
- // later
- const validAfter = Math.floor(Date.now() / 1000) + 10;
- const { v, r, s } = signTransferAuthorization(
+ // create a signed authorization that won't be valid until 1 day later
+ const validAfter = Math.floor(Date.now() / 1000) + 86400;
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -207,9 +236,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"authorization is not yet valid"
@@ -220,7 +247,7 @@ export function testTransferWithAuthorization({
// create a signed authorization that expires immediately
const { from, to, value, validAfter } = transferParams;
const validBefore = Math.floor(Date.now() / 1000);
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -240,9 +267,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"authorization is expired"
@@ -253,7 +278,7 @@ export function testTransferWithAuthorization({
const { from, to, validAfter, validBefore } = transferParams;
// create a signed authorization
const value = 1e6;
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -272,9 +297,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
);
@@ -287,9 +310,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"authorization is used or canceled"
@@ -318,9 +339,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- authorization.v,
- authorization.r,
- authorization.s,
+ ...prepareSignature(authorization, signatureBytesType),
{ from: charlie }
);
@@ -346,9 +365,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- authorization2.v,
- authorization2.r,
- authorization2.s,
+ ...prepareSignature(authorization2, signatureBytesType),
{ from: charlie }
),
"authorization is used or canceled"
@@ -360,7 +377,7 @@ export function testTransferWithAuthorization({
// create a signed authorization that attempts to transfer an amount
// that exceeds the sender's balance
const value = initialBalance + 1;
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -380,57 +397,17 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"transfer amount exceeds balance"
);
});
- it("reverts if the authorization is not for a transfer", async () => {
- const {
- from: owner,
- to: spender,
- value,
- validAfter,
- validBefore,
- } = transferParams;
- // create a signed authorization for an approval (granting allowance)
- const { v, r, s } = signApproveAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- domainSeparator,
- alice.key
- );
-
- // try to submit the approval authorization
- await expectRevert(
- fiatToken.transferWithAuthorization(
- owner,
- spender,
- value,
- validAfter,
- validBefore,
- nonce,
- v,
- r,
- s,
- { from: charlie }
- ),
- "invalid signature"
- );
- });
-
it("reverts if the contract is paused", async () => {
const { from, to, value, validAfter, validBefore } = transferParams;
// create a signed authorization
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -453,9 +430,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
),
"paused"
@@ -465,7 +440,7 @@ export function testTransferWithAuthorization({
it("reverts if the payer or the payee is blacklisted", async () => {
const { from, to, value, validAfter, validBefore } = transferParams;
// create a signed authorization
- const { v, r, s } = signTransferAuthorization(
+ const signature = signTransferAuthorization(
from,
to,
value,
@@ -487,9 +462,7 @@ export function testTransferWithAuthorization({
validAfter,
validBefore,
nonce,
- v,
- r,
- s,
+ ...prepareSignature(signature, signatureBytesType),
{ from: charlie }
);
diff --git a/test/v2/GasAbstraction/testTransferWithMultipleAuthorizations.ts b/test/v2/GasAbstraction/testTransferWithMultipleAuthorizations.ts
index 9ad169faf..7ece62bc9 100644
--- a/test/v2/GasAbstraction/testTransferWithMultipleAuthorizations.ts
+++ b/test/v2/GasAbstraction/testTransferWithMultipleAuthorizations.ts
@@ -1,9 +1,28 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import crypto from "crypto";
+import { FiatTokenUtilInstance } from "../../../@types/generated";
import {
- FiatTokenV2Instance,
- FiatTokenUtilInstance,
-} from "../../../@types/generated";
-import { ACCOUNTS_AND_KEYS, MAX_UINT256 } from "../../helpers/constants";
+ ACCOUNTS_AND_KEYS,
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_HEX,
+} from "../../helpers/constants";
import {
expectRevert,
hexStringFromBuffer,
@@ -13,6 +32,7 @@ import {
} from "../../helpers";
import { signTransferAuthorization, TestParams } from "./helpers";
import { TransactionRawLog } from "../../../@types/TransactionRawLog";
+import { AnyFiatTokenV2Instance } from "../../../@types/AnyFiatTokenV2Instance";
const FiatTokenUtil = artifacts.require("FiatTokenUtil");
const ContractThatReverts = artifacts.require("ContractThatReverts");
@@ -20,31 +40,36 @@ const ContractThatReverts = artifacts.require("ContractThatReverts");
export function testTransferWithMultipleAuthorizations({
getFiatToken,
getDomainSeparator,
- fiatTokenOwner,
- accounts,
+ signerWalletType,
}: TestParams): void {
- describe("transferWithMultipleAuthorizations", () => {
- let fiatToken: FiatTokenV2Instance;
- let fiatTokenUtil: FiatTokenUtilInstance;
- let domainSeparator: string;
+ describe(`transferWithMultipleAuthorization with ${signerWalletType} wallet`, async () => {
const [alice, bob] = ACCOUNTS_AND_KEYS;
- const charlie = accounts[1];
- let nonce: string;
-
+ const charlie = HARDHAT_ACCOUNTS[1];
+ const nonce: string = hexStringFromBuffer(crypto.randomBytes(32));
const initialBalance = 10e6;
const transferParams = {
from: alice.address,
to: bob.address,
value: 7e6,
validAfter: 0,
- validBefore: MAX_UINT256,
+ validBefore: MAX_UINT256_HEX,
+ nonce,
};
+ let fiatToken: AnyFiatTokenV2Instance;
+ let fiatTokenUtil: FiatTokenUtilInstance;
+ let domainSeparator: string;
+ let fiatTokenOwner: string;
+
+ before(async () => {
+ fiatTokenOwner = await getFiatToken().owner();
+ });
+
beforeEach(async () => {
fiatToken = getFiatToken();
fiatTokenUtil = await FiatTokenUtil.new(fiatToken.address);
domainSeparator = getDomainSeparator();
- nonce = hexStringFromBuffer(crypto.randomBytes(32));
+
await fiatToken.configureMinter(fiatTokenOwner, 1000000e6, {
from: fiatTokenOwner,
});
@@ -168,10 +193,8 @@ export function testTransferWithMultipleAuthorizations({
expect((await fiatToken.balanceOf(from)).toNumber()).to.equal(10e6);
expect((await fiatToken.balanceOf(to)).toNumber()).to.equal(0);
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(0);
+ // check that the authorization state is false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
// a third-party, Charlie (not Alice) submits the signed authorization
const result = await fiatTokenUtil.transferWithMultipleAuthorizations(
@@ -207,10 +230,8 @@ export function testTransferWithMultipleAuthorizations({
Number(web3.eth.abi.decodeParameters(["uint256"], log1.data)[0])
).to.equal(value);
- // check that the authorization state is now 1 = Used
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(1);
+ // check that the authorization state is now true
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(true);
});
it("can execute multiple transfers", async () => {
@@ -250,13 +271,9 @@ export function testTransferWithMultipleAuthorizations({
expect((await fiatToken.balanceOf(from)).toNumber()).to.equal(10e6);
expect((await fiatToken.balanceOf(to)).toNumber()).to.equal(0);
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(0);
- expect(
- (await fiatToken.authorizationState(from, nonce2)).toNumber()
- ).to.equal(0);
+ // check that the authorization state is false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
+ expect(await fiatToken.authorizationState(from, nonce2)).to.equal(false);
// a third-party, Charlie (not Alice) submits the signed authorization
const result = await fiatTokenUtil.transferWithMultipleAuthorizations(
@@ -319,13 +336,9 @@ export function testTransferWithMultipleAuthorizations({
Number(web3.eth.abi.decodeParameters(["uint256"], log3.data)[0])
).to.equal(value2);
- // check that the authorization state is now 1 = Used
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(1);
- expect(
- (await fiatToken.authorizationState(from, nonce2)).toNumber()
- ).to.equal(1);
+ // check that the authorization state is now true
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(true);
+ expect(await fiatToken.authorizationState(from, nonce2)).to.equal(true);
});
it("does not revert if one of the transfers fail, but atomic is false", async () => {
@@ -365,13 +378,9 @@ export function testTransferWithMultipleAuthorizations({
expect((await fiatToken.balanceOf(from)).toNumber()).to.equal(10e6);
expect((await fiatToken.balanceOf(to)).toNumber()).to.equal(0);
- // check that the authorization state is 0 = Unused
- expect(
- (await fiatToken.authorizationState(from, nonce)).toNumber()
- ).to.equal(0);
- expect(
- (await fiatToken.authorizationState(from, nonce2)).toNumber()
- ).to.equal(0);
+ // check that the authorization state is false
+ expect(await fiatToken.authorizationState(from, nonce)).to.equal(false);
+ expect(await fiatToken.authorizationState(from, nonce2)).to.equal(false);
// a third-party, Charlie (not Alice) submits the signed authorization
const result = await fiatTokenUtil.transferWithMultipleAuthorizations(
diff --git a/test/v2/MockFiatTokenWithEditableBalanceAndBlacklistStates.test.ts b/test/v2/MockFiatTokenWithEditableBalanceAndBlacklistStates.test.ts
new file mode 100644
index 000000000..8264c92db
--- /dev/null
+++ b/test/v2/MockFiatTokenWithEditableBalanceAndBlacklistStates.test.ts
@@ -0,0 +1,231 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import BN from "bn.js";
+import { MockFiatTokenWithEditableBalanceAndBlacklistStatesInstance } from "../../@types/generated";
+import {
+ expectRevert,
+ initializeToVersion,
+ linkLibraryToTokenContract,
+} from "../helpers";
+import {
+ ACCOUNTS_AND_KEYS,
+ HARDHAT_ACCOUNTS,
+ POW_2_255_BN,
+} from "../helpers/constants";
+
+const MockFiatTokenWithEditableBalanceAndBlacklistStates = artifacts.require(
+ "MockFiatTokenWithEditableBalanceAndBlacklistStates"
+);
+
+describe("MockFiatTokenWithEditableBalanceAndBlacklistStates", () => {
+ const userOne = ACCOUNTS_AND_KEYS[0].address;
+ const [, , lostAndFound] = HARDHAT_ACCOUNTS;
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[9];
+
+ let fiatToken: MockFiatTokenWithEditableBalanceAndBlacklistStatesInstance;
+
+ const ZERO = new BN(0);
+ const SEVEN = new BN(7, 10);
+
+ before(async () => {
+ await linkLibraryToTokenContract(
+ MockFiatTokenWithEditableBalanceAndBlacklistStates
+ );
+ });
+
+ beforeEach(async () => {
+ fiatToken = await MockFiatTokenWithEditableBalanceAndBlacklistStates.new();
+ await initializeToVersion(fiatToken, "2.2", fiatTokenOwner, lostAndFound);
+ });
+
+ async function expectBalanceAndBlacklistStatesToBe(
+ account: string,
+ expectedState: BN
+ ) {
+ const currentState = await fiatToken.getBalanceAndBlacklistStates(account);
+ expect(currentState.eq(expectedState)).to.be.true;
+ }
+
+ describe("internal_setBlacklistState", () => {
+ context("when _shouldBlacklist is true", () => {
+ const _shouldBlacklist = true;
+
+ it("should store 2^255 if the account was not blacklisted", async () => {
+ await expectBalanceAndBlacklistStatesToBe(userOne, ZERO);
+
+ await fiatToken.internal_setBlacklistState(userOne, _shouldBlacklist);
+
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+ });
+
+ it("should retain 2^255 if the account was blacklisted", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, POW_2_255_BN);
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+
+ await fiatToken.internal_setBlacklistState(userOne, _shouldBlacklist);
+
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+ });
+
+ it("should store (2^255 + previous balance) if the account has a balance", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, SEVEN);
+ await expectBalanceAndBlacklistStatesToBe(userOne, SEVEN);
+
+ await fiatToken.internal_setBlacklistState(userOne, _shouldBlacklist);
+
+ await expectBalanceAndBlacklistStatesToBe(
+ userOne,
+ POW_2_255_BN.add(SEVEN)
+ );
+ });
+ });
+
+ context("when _shouldBlacklist is false", () => {
+ const _shouldBlacklist = false;
+
+ it("should store 0 if the account was blacklisted", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, POW_2_255_BN);
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+
+ await fiatToken.internal_setBlacklistState(userOne, _shouldBlacklist);
+
+ await expectBalanceAndBlacklistStatesToBe(userOne, ZERO);
+ });
+
+ it("should retain 0 if the account was not blacklisted", async () => {
+ await expectBalanceAndBlacklistStatesToBe(userOne, ZERO);
+
+ await fiatToken.internal_setBlacklistState(userOne, _shouldBlacklist);
+
+ await expectBalanceAndBlacklistStatesToBe(userOne, ZERO);
+ });
+
+ it("should store previous balance if the account has a balance", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(
+ userOne,
+ POW_2_255_BN.add(SEVEN)
+ );
+ await expectBalanceAndBlacklistStatesToBe(
+ userOne,
+ POW_2_255_BN.add(SEVEN)
+ );
+
+ await fiatToken.internal_setBlacklistState(userOne, _shouldBlacklist);
+
+ await expectBalanceAndBlacklistStatesToBe(userOne, SEVEN);
+ });
+ });
+ });
+
+ describe("internal_setBalance", () => {
+ it("should revert if new balance is greater than or equal to 2^255", async () => {
+ await expectBalanceAndBlacklistStatesToBe(userOne, ZERO);
+
+ const newBalance = POW_2_255_BN; // 2^255
+ await expectRevert(
+ fiatToken.internal_setBalance(userOne, newBalance),
+ "FiatTokenV2_2: Balance exceeds (2^255 - 1)"
+ );
+
+ await expectBalanceAndBlacklistStatesToBe(userOne, ZERO);
+ });
+
+ it("should revert if the account is blacklisted", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, POW_2_255_BN);
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+
+ const newBalance = SEVEN;
+ await expectRevert(
+ fiatToken.internal_setBalance(userOne, newBalance),
+ "FiatTokenV2_2: Account is blacklisted"
+ );
+
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+ });
+
+ it("should always reset balances to the _balance parameter if new balance is less than 2^255 and account is not blacklisted", async () => {
+ const newBalance = POW_2_255_BN.sub(new BN(1)); // 2^255 - 1
+ await expectBalanceAndBlacklistStatesToBe(userOne, ZERO);
+
+ // Set to some high value.
+ await fiatToken.internal_setBalance(userOne, newBalance);
+ await expectBalanceAndBlacklistStatesToBe(userOne, newBalance);
+
+ // Then, choose a lower value, ensuring that it sets to the value.
+ await fiatToken.internal_setBalance(userOne, SEVEN);
+ await expectBalanceAndBlacklistStatesToBe(userOne, SEVEN);
+
+ // Then, choose a higher value, ensuring that it sets to the value.
+ await fiatToken.internal_setBalance(userOne, newBalance);
+ await expectBalanceAndBlacklistStatesToBe(userOne, newBalance);
+ });
+ });
+
+ describe("internal_isBlacklisted", () => {
+ it("should return false if the high bit is 0", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, SEVEN);
+ expect(await fiatToken.internal_isBlacklisted(userOne)).to.be.false;
+ });
+
+ it("should return true if the high bit is 1", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(
+ userOne,
+ POW_2_255_BN.add(SEVEN)
+ );
+ expect(await fiatToken.internal_isBlacklisted(userOne)).to.be.true;
+ });
+
+ it("should not change balanceAndBlacklistState", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, SEVEN);
+ await fiatToken.internal_isBlacklisted(userOne);
+ await expectBalanceAndBlacklistStatesToBe(userOne, SEVEN);
+
+ await fiatToken.setBalanceAndBlacklistStates(userOne, POW_2_255_BN);
+ await fiatToken.internal_isBlacklisted(userOne);
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+ });
+ });
+
+ describe("internal_balanceOf", () => {
+ it("should return the correct balance when the high bit is 0", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, SEVEN);
+ expect((await fiatToken.internal_balanceOf(userOne)).eq(SEVEN)).to.be
+ .true;
+ });
+
+ it("should return the correct balance when the high bit is 1", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(
+ userOne,
+ POW_2_255_BN.add(SEVEN)
+ );
+ expect((await fiatToken.internal_balanceOf(userOne)).eq(SEVEN)).to.be
+ .true;
+ });
+
+ it("should not change balanceAndBlacklistState", async () => {
+ await fiatToken.setBalanceAndBlacklistStates(userOne, SEVEN);
+ await fiatToken.internal_balanceOf(userOne);
+ await expectBalanceAndBlacklistStatesToBe(userOne, SEVEN);
+
+ await fiatToken.setBalanceAndBlacklistStates(userOne, POW_2_255_BN);
+ await fiatToken.internal_balanceOf(userOne);
+ await expectBalanceAndBlacklistStatesToBe(userOne, POW_2_255_BN);
+ });
+ });
+});
diff --git a/test/v2/MockFiatTokenWithEditableChainId.test.ts b/test/v2/MockFiatTokenWithEditableChainId.test.ts
new file mode 100644
index 000000000..f1d745d50
--- /dev/null
+++ b/test/v2/MockFiatTokenWithEditableChainId.test.ts
@@ -0,0 +1,74 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { MockFiatTokenWithEditableChainIdInstance } from "../../@types/generated";
+import { makeDomainSeparator, linkLibraryToTokenContract } from "../helpers";
+import { HARDHAT_ACCOUNTS } from "../helpers/constants";
+
+const MockFiatTokenWithEditableChainId = artifacts.require(
+ "MockFiatTokenWithEditableChainId"
+);
+
+describe("MockFiatTokenWithEditableChainId", () => {
+ const name = "USDC";
+ const version = "2";
+ const [, , lostAndFound] = HARDHAT_ACCOUNTS;
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[9];
+
+ let fiatToken: MockFiatTokenWithEditableChainIdInstance;
+
+ beforeEach(async () => {
+ await linkLibraryToTokenContract(MockFiatTokenWithEditableChainId);
+ fiatToken = await MockFiatTokenWithEditableChainId.new();
+
+ await fiatToken.initialize(
+ name,
+ "USDC",
+ "USD",
+ 6,
+ fiatTokenOwner,
+ fiatTokenOwner,
+ fiatTokenOwner,
+ fiatTokenOwner
+ );
+ await fiatToken.initializeV2("USDC", { from: fiatTokenOwner });
+ await fiatToken.initializeV2_1(lostAndFound);
+ await fiatToken.initializeV2_2([], "USDCUSDC");
+ });
+
+ describe("DOMAIN_SEPARATOR", () => {
+ it("domain separator gets recalculated after chain ID changes", async () => {
+ const chainId: number = (await fiatToken.chainId()).toNumber();
+ const originalDomainSeparator: string = await fiatToken.DOMAIN_SEPARATOR();
+ assert.equal(
+ originalDomainSeparator,
+ makeDomainSeparator(name, version, chainId, fiatToken.address)
+ );
+
+ const newChainId = 1234;
+ await fiatToken.setChainId(newChainId);
+
+ const newDomainSeparator: string = await fiatToken.DOMAIN_SEPARATOR();
+
+ assert.equal(
+ newDomainSeparator,
+ makeDomainSeparator(name, version, newChainId, fiatToken.address)
+ );
+ });
+ });
+});
diff --git a/test/v2/V2Upgrader.test.ts b/test/v2/V2Upgrader.test.ts
index ab60cd522..694bc7335 100644
--- a/test/v2/V2Upgrader.test.ts
+++ b/test/v2/V2Upgrader.test.ts
@@ -1,3 +1,21 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import crypto from "crypto";
import {
FiatTokenV1Instance,
@@ -5,8 +23,16 @@ import {
FiatTokenProxyInstance,
} from "../../@types/generated";
import { signTransferAuthorization } from "./GasAbstraction/helpers";
-import { MAX_UINT256, ACCOUNTS_AND_KEYS } from "../helpers/constants";
-import { hexStringFromBuffer, expectRevert } from "../helpers";
+import {
+ MAX_UINT256_HEX,
+ ACCOUNTS_AND_KEYS,
+ accounts,
+} from "../helpers/constants";
+import {
+ hexStringFromBuffer,
+ expectRevert,
+ linkLibraryToTokenContract,
+} from "../helpers";
const FiatTokenProxy = artifacts.require("FiatTokenProxy");
const FiatTokenV1 = artifacts.require("FiatTokenV1");
@@ -14,22 +40,43 @@ const FiatTokenV1_1 = artifacts.require("FiatTokenV1_1");
const FiatTokenV2 = artifacts.require("FiatTokenV2");
const V2Upgrader = artifacts.require("V2Upgrader");
-contract("V2Upgrader", (accounts) => {
+describe("V2Upgrader", () => {
let fiatTokenProxy: FiatTokenProxyInstance;
let proxyAsV1: FiatTokenV1Instance;
let proxyAsV2: FiatTokenV2Instance;
let v1Implementation: FiatTokenV1Instance;
let v2Implementation: FiatTokenV2Instance;
- let originalProxyAdmin: string;
- const minter = accounts[9];
+ const {
+ minterAccount: minter,
+ masterMinterAccount,
+ pauserAccount,
+ blacklisterAccount,
+ tokenOwnerAccount,
+ proxyOwnerAccount: originalProxyAdmin,
+ } = accounts;
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2);
+ });
beforeEach(async () => {
- fiatTokenProxy = await FiatTokenProxy.deployed();
+ v1Implementation = await FiatTokenV1.new();
+ v2Implementation = await FiatTokenV2.new();
+ fiatTokenProxy = await FiatTokenProxy.new(v1Implementation.address, {
+ from: originalProxyAdmin,
+ });
proxyAsV1 = await FiatTokenV1.at(fiatTokenProxy.address);
+ await proxyAsV1.initialize(
+ "USD//C",
+ "USDC",
+ "USD",
+ 6,
+ masterMinterAccount,
+ pauserAccount,
+ blacklisterAccount,
+ tokenOwnerAccount
+ );
proxyAsV2 = await FiatTokenV2.at(fiatTokenProxy.address);
- v1Implementation = await FiatTokenV1.deployed();
- v2Implementation = await FiatTokenV2.deployed();
- originalProxyAdmin = await fiatTokenProxy.admin();
await proxyAsV1.configureMinter(minter, 2e5, {
from: await proxyAsV1.masterMinter(),
@@ -41,7 +88,12 @@ contract("V2Upgrader", (accounts) => {
it("upgrades, transfers proxy admin role to newProxyAdmin, runs tests, and self-destructs", async () => {
// Run the test on the contracts deployed by Truffle to ensure the Truffle
// migration is written correctly
- const upgrader = await V2Upgrader.deployed();
+ const upgrader = await V2Upgrader.new(
+ fiatTokenProxy.address,
+ v2Implementation.address,
+ await fiatTokenProxy.admin(),
+ "USDC"
+ );
const upgraderOwner = await upgrader.owner();
expect(await upgrader.proxy()).to.equal(fiatTokenProxy.address);
@@ -50,9 +102,9 @@ contract("V2Upgrader", (accounts) => {
);
expect(await upgrader.helper()).not.to.be.empty;
expect(await upgrader.newProxyAdmin()).to.equal(originalProxyAdmin);
- expect(await upgrader.newName()).to.equal("USD Coin");
+ expect(await upgrader.newName()).to.equal("USDC");
- // Transfer 0.2 USDC to the contract
+ // Transfer 0.2 FiatToken to the contract
await proxyAsV1.transfer(upgrader.address, 2e5, { from: minter });
// Transfer admin role to the contract
@@ -72,7 +124,7 @@ contract("V2Upgrader", (accounts) => {
);
// Test that things work as expected
- expect(await proxyAsV2.name()).to.equal("USD Coin");
+ expect(await proxyAsV2.name()).to.equal("USDC");
expect((await proxyAsV2.balanceOf(upgrader.address)).toNumber()).to.equal(
0
);
@@ -94,7 +146,7 @@ contract("V2Upgrader", (accounts) => {
minter,
1e5,
0,
- MAX_UINT256,
+ MAX_UINT256_HEX,
nonce,
await proxyAsV2.DOMAIN_SEPARATOR(),
user2.key // Signed with someone else's key
@@ -106,7 +158,7 @@ contract("V2Upgrader", (accounts) => {
minter,
1e5,
0,
- MAX_UINT256,
+ MAX_UINT256_HEX,
nonce,
invalidAuthorization.v,
invalidAuthorization.r,
@@ -121,7 +173,7 @@ contract("V2Upgrader", (accounts) => {
minter,
1e5,
0,
- MAX_UINT256,
+ MAX_UINT256_HEX,
nonce,
await proxyAsV2.DOMAIN_SEPARATOR(),
user.key
@@ -133,7 +185,7 @@ contract("V2Upgrader", (accounts) => {
minter,
1e5,
0,
- MAX_UINT256,
+ MAX_UINT256_HEX,
nonce,
validAuthorization.v,
validAuthorization.r,
@@ -152,17 +204,17 @@ contract("V2Upgrader", (accounts) => {
from: originalProxyAdmin,
});
const fiatTokenV1_1 = await FiatTokenV1_1.new();
- const upgraderOwner = accounts[0];
+ const upgraderOwner = accounts.deployerAccount;
const upgrader = await V2Upgrader.new(
fiatTokenProxy.address,
fiatTokenV1_1.address, // provide V1.1 implementation instead of V2
originalProxyAdmin,
- "USD Coin",
+ "USDC",
{ from: upgraderOwner }
);
- // Transfer 0.2 USDC to the contract
+ // Transfer 0.2 FiatToken to the contract
await proxyAsV1.transfer(upgrader.address, 2e5, { from: minter });
// Transfer admin role to the contract
@@ -188,16 +240,16 @@ contract("V2Upgrader", (accounts) => {
fiatTokenProxy = await FiatTokenProxy.new(v1Implementation.address, {
from: originalProxyAdmin,
});
- const upgraderOwner = accounts[0];
+ const upgraderOwner = accounts.deployerAccount;
const upgrader = await V2Upgrader.new(
fiatTokenProxy.address,
v2Implementation.address,
originalProxyAdmin,
- "USD Coin",
+ "USDC",
{ from: upgraderOwner }
);
- // Transfer 0.2 USDC to the contract
+ // Transfer 0.2 FiatToken to the contract
await proxyAsV1.transfer(upgrader.address, 2e5, { from: minter });
// Transfer admin role to the contract
diff --git a/test/v2/V2_1Upgrader.test.ts b/test/v2/V2_1Upgrader.test.ts
new file mode 100644
index 000000000..a8766259c
--- /dev/null
+++ b/test/v2/V2_1Upgrader.test.ts
@@ -0,0 +1,273 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ FiatTokenV2Instance,
+ FiatTokenV2_1Instance,
+ FiatTokenProxyInstance,
+} from "../../@types/generated";
+import { strip0x, expectRevert, linkLibraryToTokenContract } from "../helpers";
+import { accounts } from "../helpers/constants";
+
+const FiatTokenProxy = artifacts.require("FiatTokenProxy");
+const FiatTokenV1_1 = artifacts.require("FiatTokenV1_1");
+const FiatTokenV2 = artifacts.require("FiatTokenV2");
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+const V2_1Upgrader = artifacts.require("V2_1Upgrader");
+
+describe("V2_1Upgrader", () => {
+ let fiatTokenProxy: FiatTokenProxyInstance;
+ let proxyAsV2: FiatTokenV2Instance;
+ let proxyAsV2_1: FiatTokenV2_1Instance;
+ let v2Implementation: FiatTokenV2Instance;
+ let v2_1Implementation: FiatTokenV2_1Instance;
+
+ const {
+ minterAccount: minter,
+ proxyOwnerAccount: originalProxyAdmin,
+ lostAndFoundAccount: lostAndFound,
+ arbitraryAccount: alice,
+ arbitraryAccount2: bob,
+ masterMinterAccount,
+ pauserAccount,
+ blacklisterAccount,
+ tokenOwnerAccount,
+ } = accounts;
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2);
+ await linkLibraryToTokenContract(FiatTokenV2_1);
+
+ v2Implementation = await FiatTokenV2.new();
+ v2_1Implementation = await FiatTokenV2_1.new();
+ fiatTokenProxy = await FiatTokenProxy.new(v2Implementation.address, {
+ from: originalProxyAdmin,
+ });
+
+ proxyAsV2 = await FiatTokenV2.at(fiatTokenProxy.address);
+ proxyAsV2_1 = await FiatTokenV2_1.at(fiatTokenProxy.address);
+ await proxyAsV2.initialize(
+ "USD//C",
+ "USDC",
+ "USD",
+ 6,
+ masterMinterAccount,
+ pauserAccount,
+ blacklisterAccount,
+ tokenOwnerAccount
+ );
+
+ // Upgrade from v1 to v2
+ await fiatTokenProxy.upgradeToAndCall(
+ v2Implementation.address,
+ web3.eth.abi.encodeFunctionSignature("initializeV2(string)") +
+ strip0x(web3.eth.abi.encodeParameters(["string"], ["USDC"])),
+ { from: originalProxyAdmin }
+ );
+ });
+
+ beforeEach(async () => {
+ await proxyAsV2.configureMinter(minter, 1000e6, {
+ from: await proxyAsV2.masterMinter(),
+ });
+ await proxyAsV2.mint(minter, 100e6 + 2e5, { from: minter });
+ });
+
+ describe("upgrade", () => {
+ it("upgrades, transfers proxy admin role to newProxyAdmin, runs tests, and self-destructs", async () => {
+ const upgrader = await V2_1Upgrader.new(
+ fiatTokenProxy.address,
+ v2_1Implementation.address,
+ originalProxyAdmin,
+ lostAndFound
+ );
+ const upgraderOwner = await upgrader.owner();
+
+ expect(await upgrader.proxy()).to.equal(fiatTokenProxy.address);
+ expect(await upgrader.implementation()).to.equal(
+ v2_1Implementation.address
+ );
+ expect(await upgrader.helper()).not.to.be.empty;
+ expect(await upgrader.newProxyAdmin()).to.equal(originalProxyAdmin);
+ expect(await upgrader.lostAndFound()).to.equal(lostAndFound);
+
+ // Transfer 0.2 FiatToken to the upgrader contract
+ await proxyAsV2.transfer(upgrader.address, 2e5, { from: minter });
+
+ // Transfer 100 FiatToken to the FiatTokenProxy contract
+ await proxyAsV2.transfer(proxyAsV2_1.address, 100e6, { from: minter });
+
+ // Transfer admin role to the contract
+ await fiatTokenProxy.changeAdmin(upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Call upgrade
+ await upgrader.upgrade({ from: upgraderOwner });
+
+ // The proxy admin role is transferred back to originalProxyAdmin
+ expect(await fiatTokenProxy.admin()).to.equal(originalProxyAdmin);
+
+ // The implementation is updated to V2.1
+ expect(await fiatTokenProxy.implementation()).to.equal(
+ v2_1Implementation.address
+ );
+
+ // 0.2 FiatToken is transferred back to the upgraderOwner
+ expect(
+ (await proxyAsV2_1.balanceOf(upgrader.address)).toNumber()
+ ).to.equal(0);
+ expect((await proxyAsV2_1.balanceOf(upgraderOwner)).toNumber()).to.equal(
+ 2e5
+ );
+
+ // the FiatToken tokens held by the proxy contract are transferred to the lost
+ // and found address
+ expect(
+ (await proxyAsV2_1.balanceOf(proxyAsV2_1.address)).toNumber()
+ ).to.equal(0);
+
+ expect((await proxyAsV2_1.balanceOf(lostAndFound)).toNumber()).to.equal(
+ 100e6
+ );
+
+ // token proxy contract is blacklisted
+ expect(await proxyAsV2_1.isBlacklisted(proxyAsV2_1.address)).to.equal(
+ true
+ );
+
+ // mint works as expected
+ await proxyAsV2_1.configureMinter(minter, 1000e6, {
+ from: await proxyAsV2_1.masterMinter(),
+ });
+ await proxyAsV2_1.mint(alice, 1000e6, { from: minter });
+ expect((await proxyAsV2_1.balanceOf(alice)).toNumber()).to.equal(1000e6);
+
+ await expectRevert(
+ proxyAsV2_1.mint(alice, 1, { from: alice }),
+ "caller is not a minter"
+ );
+
+ // transfer works as expected
+ await proxyAsV2_1.transfer(bob, 200e6, { from: alice });
+ expect((await proxyAsV2_1.balanceOf(alice)).toNumber()).to.equal(800e6);
+ expect((await proxyAsV2_1.balanceOf(bob)).toNumber()).to.equal(200e6);
+
+ await expectRevert(
+ proxyAsV2_1.transfer(proxyAsV2_1.address, 1, { from: alice }),
+ "account is blacklisted"
+ );
+
+ // approve/transferFrom work as expected
+ await proxyAsV2_1.approve(bob, 250e6, { from: alice });
+ expect((await proxyAsV2_1.allowance(alice, bob)).toNumber()).to.equal(
+ 250e6
+ );
+ await proxyAsV2_1.transferFrom(alice, bob, 250e6, { from: bob });
+ expect((await proxyAsV2_1.allowance(alice, bob)).toNumber()).to.equal(0);
+ expect((await proxyAsV2_1.balanceOf(alice)).toNumber()).to.equal(550e6);
+ expect((await proxyAsV2_1.balanceOf(bob)).toNumber()).to.equal(450e6);
+
+ await expectRevert(
+ proxyAsV2_1.approve(proxyAsV2_1.address, 1, { from: alice }),
+ "account is blacklisted"
+ );
+
+ // burn works as expected
+ await proxyAsV2_1.transfer(minter, 100e6, { from: alice });
+ expect((await proxyAsV2_1.balanceOf(minter)).toNumber()).to.equal(100e6);
+ await proxyAsV2_1.burn(100e6, { from: minter });
+ expect((await proxyAsV2_1.balanceOf(minter)).toNumber()).to.equal(0);
+
+ await expectRevert(
+ proxyAsV2_1.burn(1, { from: alice }),
+ "caller is not a minter"
+ );
+ });
+
+ it("reverts if there is an error", async () => {
+ fiatTokenProxy = await FiatTokenProxy.new(v2Implementation.address, {
+ from: originalProxyAdmin,
+ });
+ const fiatTokenV1_1 = await FiatTokenV1_1.new();
+ const upgraderOwner = accounts.deployerAccount;
+
+ const upgrader = await V2_1Upgrader.new(
+ fiatTokenProxy.address,
+ fiatTokenV1_1.address, // provide V1.1 implementation instead of V2.1
+ originalProxyAdmin,
+ lostAndFound,
+ { from: upgraderOwner }
+ );
+
+ // Transfer 0.2 FiatToken to the contract
+ await proxyAsV2.transfer(upgrader.address, 2e5, { from: minter });
+
+ // Transfer admin role to the contract
+ await fiatTokenProxy.changeAdmin(upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Upgrade should fail because initializeV2_1 function doesn't exist on V1.1
+ await expectRevert(upgrader.upgrade({ from: upgraderOwner }), "revert");
+
+ // The proxy admin role is not transferred
+ expect(await fiatTokenProxy.admin()).to.equal(upgrader.address);
+
+ // The implementation is left unchanged
+ expect(await fiatTokenProxy.implementation()).to.equal(
+ v2Implementation.address
+ );
+ });
+ });
+
+ describe("abortUpgrade", () => {
+ it("transfers proxy admin role to newProxyAdmin and self-destructs", async () => {
+ fiatTokenProxy = await FiatTokenProxy.new(v2Implementation.address, {
+ from: originalProxyAdmin,
+ });
+ const upgraderOwner = accounts.deployerAccount;
+ const upgrader = await V2_1Upgrader.new(
+ fiatTokenProxy.address,
+ v2_1Implementation.address,
+ originalProxyAdmin,
+ lostAndFound,
+ { from: upgraderOwner }
+ );
+
+ // Transfer 0.2 FiatToken to the contract
+ await proxyAsV2.transfer(upgrader.address, 2e5, { from: minter });
+
+ // Transfer admin role to the contract
+ await fiatTokenProxy.changeAdmin(upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Call abortUpgrade
+ await upgrader.abortUpgrade({ from: upgraderOwner });
+
+ // The proxy admin role is transferred back to originalProxyAdmin
+ expect(await fiatTokenProxy.admin()).to.equal(originalProxyAdmin);
+
+ // The implementation is left unchanged
+ expect(await fiatTokenProxy.implementation()).to.equal(
+ v2Implementation.address
+ );
+ });
+ });
+});
diff --git a/test/v2/V2_2Upgrader.test.ts b/test/v2/V2_2Upgrader.test.ts
new file mode 100644
index 000000000..f2d2d64e1
--- /dev/null
+++ b/test/v2/V2_2Upgrader.test.ts
@@ -0,0 +1,483 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ FiatTokenProxyInstance,
+ FiatTokenV2_1Instance,
+ FiatTokenV2_2Instance,
+ V2_2UpgraderInstance,
+} from "../../@types/generated";
+import {
+ expectRevert,
+ generateAccounts,
+ initializeToVersion,
+ linkLibraryToTokenContract,
+} from "../helpers";
+import { toLower } from "lodash";
+import { BLOCK_GAS_LIMIT, accounts } from "../helpers/constants";
+
+const FiatTokenProxy = artifacts.require("FiatTokenProxy");
+const FiatTokenV1_1 = artifacts.require("FiatTokenV1_1");
+const FiatTokenV2_1 = artifacts.require("FiatTokenV2_1");
+const FiatTokenV2_2 = artifacts.require("FiatTokenV2_2");
+const V2_2Upgrader = artifacts.require("V2_2Upgrader");
+
+const {
+ minterAccount: minter,
+ proxyOwnerAccount: originalProxyAdmin,
+ lostAndFoundAccount: lostAndFound,
+ arbitraryAccount: alice,
+ arbitraryAccount2: bob,
+ masterMinterAccount: v2_1MasterMinter,
+ pauserAccount,
+ blacklisterAccount,
+ tokenOwnerAccount,
+} = accounts;
+
+describe("V2_2Upgrader", () => {
+ let fiatTokenProxy: FiatTokenProxyInstance;
+ let proxyAsV2_1: FiatTokenV2_1Instance;
+ let proxyAsV2_2: FiatTokenV2_2Instance;
+ let v2_1Implementation: FiatTokenV2_1Instance;
+ let v2_2Implementation: FiatTokenV2_2Instance;
+ let v2_2Upgrader: V2_2UpgraderInstance;
+ let upgraderOwner: string;
+
+ const newSymbol = "USDCUSDC"; // Use a symbol different from original symbol
+ const accountsToBlacklist = generateAccounts(10);
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenV2_1);
+ await linkLibraryToTokenContract(FiatTokenV2_2);
+
+ v2_1Implementation = await FiatTokenV2_1.new();
+ v2_2Implementation = await FiatTokenV2_2.new();
+ fiatTokenProxy = await FiatTokenProxy.new(v2_1Implementation.address, {
+ from: originalProxyAdmin,
+ });
+ v2_2Upgrader = await V2_2Upgrader.new(
+ fiatTokenProxy.address,
+ v2_2Implementation.address,
+ await fiatTokenProxy.admin(),
+ accountsToBlacklist,
+ newSymbol
+ );
+
+ proxyAsV2_1 = await FiatTokenV2_1.at(fiatTokenProxy.address);
+ proxyAsV2_2 = await FiatTokenV2_2.at(fiatTokenProxy.address);
+ upgraderOwner = await v2_2Upgrader.owner();
+
+ // Upgrade from v1 to v2.1
+ await proxyAsV2_1.initialize(
+ "USD//C",
+ "USDC",
+ "USD",
+ 6,
+ v2_1MasterMinter,
+ pauserAccount,
+ blacklisterAccount,
+ tokenOwnerAccount
+ );
+ await fiatTokenProxy.upgradeTo(v2_1Implementation.address, {
+ from: originalProxyAdmin,
+ });
+ await proxyAsV2_1.initializeV2("USDC");
+ await proxyAsV2_1.initializeV2_1(lostAndFound);
+
+ // Initially blacklist all these accounts.
+ await Promise.all(
+ accountsToBlacklist.map((account) =>
+ proxyAsV2_2.blacklist(account, { from: blacklisterAccount })
+ )
+ );
+ });
+
+ describe("proxy", () => {
+ it("should return the correct address", async () => {
+ expect(await v2_2Upgrader.proxy()).to.equal(fiatTokenProxy.address);
+ });
+ });
+
+ describe("implementation", () => {
+ it("should return the correct address", async () => {
+ expect(await v2_2Upgrader.implementation()).to.equal(
+ v2_2Implementation.address
+ );
+ });
+ });
+
+ describe("helper", () => {
+ it("should be non empty", async () => {
+ expect(await v2_2Upgrader.helper()).to.not.be.empty;
+ });
+ });
+
+ describe("newProxyAdmin", () => {
+ it("should return the correct address", async () => {
+ expect(await v2_2Upgrader.newProxyAdmin()).to.equal(originalProxyAdmin);
+ });
+ });
+
+ describe("accountsToBlacklist", () => {
+ it("should return the correct list of addresses", async () => {
+ const actualAccountsToBlacklist = await v2_2Upgrader.accountsToBlacklist();
+ expect(actualAccountsToBlacklist.map(toLower)).to.deep.equal(
+ accountsToBlacklist.map(toLower)
+ );
+ });
+ });
+
+ describe("withdrawFiatToken", () => {
+ it("should return the FiatToken to the transaction sender", async () => {
+ // Mint 0.2 FiatToken.
+ await proxyAsV2_1.configureMinter(minter, 2e5, {
+ from: v2_1MasterMinter,
+ });
+ await proxyAsV2_1.mint(minter, 2e5, { from: minter });
+ expect((await proxyAsV2_1.balanceOf(minter)).toNumber()).to.equal(2e5);
+ expect(
+ (await proxyAsV2_1.balanceOf(v2_2Upgrader.address)).toNumber()
+ ).to.equal(0);
+
+ // Transfer 0.2 FiatToken to the upgrader contract.
+ await proxyAsV2_1.transfer(v2_2Upgrader.address, 2e5, { from: minter });
+ expect((await proxyAsV2_1.balanceOf(minter)).toNumber()).to.equal(0);
+ expect(
+ (await proxyAsV2_1.balanceOf(v2_2Upgrader.address)).toNumber()
+ ).to.equal(2e5);
+
+ // Withdraw the FiatToken from the upgrader contract.
+ await v2_2Upgrader.withdrawFiatToken({ from: upgraderOwner });
+ expect((await proxyAsV2_1.balanceOf(upgraderOwner)).toNumber()).to.equal(
+ 2e5
+ );
+ expect(
+ (await proxyAsV2_1.balanceOf(v2_2Upgrader.address)).toNumber()
+ ).to.equal(0);
+
+ // Cleanup - Burn 0.2 FiatToken.
+ await proxyAsV2_1.transfer(minter, 2e5, { from: upgraderOwner });
+ await proxyAsV2_1.burn(2e5, { from: minter });
+ });
+ });
+
+ describe("upgrade", () => {
+ it("upgrades, transfers proxy admin role to newProxyAdmin, runs tests, and self-destructs", async () => {
+ // Transfer 0.2 FiatToken to the upgrader contract
+ await proxyAsV2_1.configureMinter(minter, 2e5, {
+ from: v2_1MasterMinter,
+ });
+ await proxyAsV2_1.mint(minter, 2e5, { from: minter });
+ await proxyAsV2_1.transfer(v2_2Upgrader.address, 2e5, { from: minter });
+
+ // Transfer admin role to the contract
+ await fiatTokenProxy.changeAdmin(v2_2Upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Call upgrade
+ await v2_2Upgrader.upgrade({ from: upgraderOwner });
+
+ // The proxy admin role is transferred back to originalProxyAdmin
+ expect(await fiatTokenProxy.admin()).to.equal(originalProxyAdmin);
+
+ // The implementation is updated to V2.2
+ expect(await fiatTokenProxy.implementation()).to.equal(
+ v2_2Implementation.address
+ );
+
+ // 0.2 FiatToken is transferred back to the upgraderOwner
+ expect(
+ (await proxyAsV2_2.balanceOf(v2_2Upgrader.address)).toNumber()
+ ).to.equal(0);
+ expect((await proxyAsV2_2.balanceOf(upgraderOwner)).toNumber()).to.equal(
+ 2e5
+ );
+
+ // token proxy contract is blacklisted
+ expect(await proxyAsV2_2.isBlacklisted(proxyAsV2_2.address)).to.equal(
+ true
+ );
+
+ // All accountsToBlacklist are still blacklisted
+ const areAccountsBlacklisted = await Promise.all(
+ accountsToBlacklist.map((account) => proxyAsV2_2.isBlacklisted(account))
+ );
+ expect(areAccountsBlacklisted.every((b: boolean) => b)).to.be.true;
+
+ // mint works as expected
+ await proxyAsV2_2.configureMinter(minter, 1000e6, {
+ from: await proxyAsV2_2.masterMinter(),
+ });
+ expect((await proxyAsV2_2.minterAllowance(minter)).toNumber()).to.equal(
+ 1000e6
+ );
+ await proxyAsV2_2.mint(alice, 1000e6, { from: minter });
+ expect((await proxyAsV2_2.balanceOf(alice)).toNumber()).to.equal(1000e6);
+ expect((await proxyAsV2_2.minterAllowance(minter)).toNumber()).to.equal(
+ 0
+ );
+
+ await expectRevert(
+ proxyAsV2_2.mint(alice, 1, { from: alice }),
+ "caller is not a minter"
+ );
+
+ // transfer works as expected
+ await proxyAsV2_2.transfer(bob, 200e6, { from: alice });
+ expect((await proxyAsV2_2.balanceOf(alice)).toNumber()).to.equal(800e6);
+ expect((await proxyAsV2_2.balanceOf(bob)).toNumber()).to.equal(200e6);
+
+ await expectRevert(
+ proxyAsV2_2.transfer(proxyAsV2_2.address, 1, { from: alice }),
+ "account is blacklisted"
+ );
+
+ // approve/transferFrom work as expected
+ await proxyAsV2_2.approve(bob, 250e6, { from: alice });
+ expect((await proxyAsV2_2.allowance(alice, bob)).toNumber()).to.equal(
+ 250e6
+ );
+ await proxyAsV2_2.transferFrom(alice, bob, 250e6, { from: bob });
+ expect((await proxyAsV2_2.allowance(alice, bob)).toNumber()).to.equal(0);
+ expect((await proxyAsV2_2.balanceOf(alice)).toNumber()).to.equal(550e6);
+ expect((await proxyAsV2_2.balanceOf(bob)).toNumber()).to.equal(450e6);
+
+ // burn works as expected
+ await proxyAsV2_2.transfer(minter, 100e6, { from: alice });
+ expect((await proxyAsV2_2.balanceOf(minter)).toNumber()).to.equal(100e6);
+ await proxyAsV2_2.burn(100e6, { from: minter });
+ expect((await proxyAsV2_2.balanceOf(minter)).toNumber()).to.equal(0);
+
+ await expectRevert(
+ proxyAsV2_2.burn(1, { from: alice }),
+ "caller is not a minter"
+ );
+ });
+
+ it("reverts if there is an error", async () => {
+ const _fiatTokenProxy = await FiatTokenProxy.new(
+ v2_1Implementation.address,
+ { from: originalProxyAdmin }
+ );
+ await initializeToVersion(_fiatTokenProxy, "2.1", minter, lostAndFound);
+ const _proxyAsV2_1 = await FiatTokenV2_1.at(_fiatTokenProxy.address);
+
+ const _v1_1Implementation = await FiatTokenV1_1.new();
+ const upgraderOwner = accounts.deployerAccount;
+
+ const _v2_2Upgrader = await V2_2Upgrader.new(
+ _fiatTokenProxy.address,
+ _v1_1Implementation.address, // provide V1.1 implementation instead of V2.2
+ originalProxyAdmin,
+ [],
+ newSymbol,
+ { from: upgraderOwner }
+ );
+
+ // Transfer 0.2 FiatToken to the contract
+ await _proxyAsV2_1.configureMinter(minter, 2e5, {
+ from: await _proxyAsV2_1.masterMinter(),
+ });
+ await _proxyAsV2_1.mint(minter, 2e5, { from: minter });
+ await _proxyAsV2_1.transfer(_v2_2Upgrader.address, 2e5, { from: minter });
+
+ // Transfer admin role to the contract
+ await _fiatTokenProxy.changeAdmin(_v2_2Upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Upgrade should fail because initializeV2_2 function doesn't exist on V1.1
+ await expectRevert(
+ _v2_2Upgrader.upgrade({ from: upgraderOwner }),
+ "revert"
+ );
+
+ // The proxy admin role is not transferred
+ expect(await _fiatTokenProxy.admin()).to.equal(_v2_2Upgrader.address);
+
+ // The implementation is left unchanged
+ expect(await _fiatTokenProxy.implementation()).to.equal(
+ v2_1Implementation.address
+ );
+ });
+
+ it("reverts if blacklisting an account that was not blacklisted", async () => {
+ const _fiatTokenProxy = await FiatTokenProxy.new(
+ v2_1Implementation.address,
+ { from: originalProxyAdmin }
+ );
+ await initializeToVersion(_fiatTokenProxy, "2.1", minter, lostAndFound);
+ const _proxyAsV2_1 = await FiatTokenV2_1.at(_fiatTokenProxy.address);
+
+ const _v2_2Implementation = await FiatTokenV2_2.new();
+ const upgraderOwner = accounts.deployerAccount;
+
+ // Try blacklisting an account that was not originally blacklisted.
+ const accountsToBlacklist = generateAccounts(1);
+ const _v2_2Upgrader = await V2_2Upgrader.new(
+ _fiatTokenProxy.address,
+ _v2_2Implementation.address,
+ originalProxyAdmin,
+ accountsToBlacklist,
+ newSymbol,
+ { from: upgraderOwner }
+ );
+
+ // Transfer 0.2 FiatToken to the contract
+ await _proxyAsV2_1.configureMinter(minter, 2e5, {
+ from: await _proxyAsV2_1.masterMinter(),
+ });
+ await _proxyAsV2_1.mint(minter, 2e5, { from: minter });
+ await _proxyAsV2_1.transfer(_v2_2Upgrader.address, 2e5, { from: minter });
+
+ // Transfer admin role to the contract
+ await _fiatTokenProxy.changeAdmin(_v2_2Upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Upgrade should fail because the account to blacklist was not previously blacklisted.
+ await expectRevert(
+ _v2_2Upgrader.upgrade({ from: upgraderOwner }),
+ "FiatTokenV2_2: Blacklisting previously unblacklisted account!"
+ );
+
+ // The proxy admin role is not transferred
+ expect(await _fiatTokenProxy.admin()).to.equal(_v2_2Upgrader.address);
+
+ // The implementation is left unchanged
+ expect(await _fiatTokenProxy.implementation()).to.equal(
+ v2_1Implementation.address
+ );
+ });
+
+ describe("gas tests", () => {
+ const gasTests: [number, number][] = [
+ [100, BLOCK_GAS_LIMIT * 0.1],
+ [500, BLOCK_GAS_LIMIT * 0.5],
+ ];
+ gasTests.forEach(([numAccounts, gasTarget]) => {
+ it(`should not exceed ${gasTarget} gas when blacklisting ${numAccounts} accounts`, async () => {
+ const accountsToBlacklist = generateAccounts(numAccounts);
+
+ const _fiatTokenProxy = await FiatTokenProxy.new(
+ v2_1Implementation.address,
+ { from: originalProxyAdmin }
+ );
+ await initializeToVersion(
+ _fiatTokenProxy,
+ "2.1",
+ minter,
+ lostAndFound
+ );
+ const _proxyAsV2_1 = await FiatTokenV2_1.at(_fiatTokenProxy.address);
+
+ // Blacklist the accounts in _deprecatedBlacklist first
+ await Promise.all(
+ accountsToBlacklist.map((a) =>
+ _proxyAsV2_1.blacklist(a, { from: minter })
+ )
+ );
+
+ // Set up the V2_2Upgrader
+ const _v2_2Implementation = await FiatTokenV2_2.new();
+ const upgraderOwner = accounts.deployerAccount;
+ const _v2_2Upgrader = await V2_2Upgrader.new(
+ _fiatTokenProxy.address,
+ _v2_2Implementation.address,
+ originalProxyAdmin,
+ accountsToBlacklist,
+ newSymbol,
+ { from: upgraderOwner, gas: BLOCK_GAS_LIMIT }
+ );
+
+ // Transfer 0.2 FiatToken to the contract
+ await _proxyAsV2_1.configureMinter(minter, 2e5, {
+ from: await _proxyAsV2_1.masterMinter(),
+ });
+ await _proxyAsV2_1.mint(minter, 2e5, { from: minter });
+ await _proxyAsV2_1.transfer(_v2_2Upgrader.address, 2e5, {
+ from: minter,
+ });
+
+ // Transfer admin role to the contract
+ await _fiatTokenProxy.changeAdmin(_v2_2Upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Perform the upgrade.
+ const txReceipt = await _v2_2Upgrader.upgrade({
+ from: upgraderOwner,
+ gas: BLOCK_GAS_LIMIT,
+ });
+ const gasUsed = txReceipt.receipt.gasUsed;
+ console.log({ numAccounts, gasUsed });
+ expect(gasUsed).to.be.lessThan(gasTarget);
+
+ // Sanity check that upgrade worked.
+ expect(await _fiatTokenProxy.implementation()).to.equal(
+ _v2_2Implementation.address
+ );
+ });
+ });
+ });
+ });
+
+ describe("abortUpgrade", () => {
+ it("transfers proxy admin role to newProxyAdmin, and self-destructs", async () => {
+ const _fiatTokenProxy = await FiatTokenProxy.new(
+ v2_1Implementation.address,
+ { from: originalProxyAdmin }
+ );
+ await initializeToVersion(_fiatTokenProxy, "2.1", minter, lostAndFound);
+
+ const upgraderOwner = accounts.deployerAccount;
+ const _v2_2Upgrader = await V2_2Upgrader.new(
+ _fiatTokenProxy.address,
+ v2_1Implementation.address,
+ originalProxyAdmin,
+ [],
+ newSymbol,
+ { from: upgraderOwner }
+ );
+ const _v2_2UpgraderHelperAddress = await _v2_2Upgrader.helper();
+
+ // Transfer admin role to the contract
+ await _fiatTokenProxy.changeAdmin(_v2_2Upgrader.address, {
+ from: originalProxyAdmin,
+ });
+
+ // Call abortUpgrade
+ await _v2_2Upgrader.abortUpgrade({ from: upgraderOwner });
+
+ // The proxy admin role is transferred back to originalProxyAdmin
+ expect(await _fiatTokenProxy.admin()).to.equal(originalProxyAdmin);
+
+ // The implementation is left unchanged
+ expect(await _fiatTokenProxy.implementation()).to.equal(
+ v2_1Implementation.address
+ );
+
+ // The upgrader contract is self-destructed.
+ expect(await web3.eth.getCode(_v2_2Upgrader.address)).to.equal("0x");
+
+ // The upgrader helper contract is self-destructed.
+ expect(await web3.eth.getCode(_v2_2UpgraderHelperAddress)).to.equal("0x");
+ });
+ });
+});
diff --git a/test/v2/celo/FiatTokenCeloV2_2.test.ts b/test/v2/celo/FiatTokenCeloV2_2.test.ts
new file mode 100644
index 000000000..d23df5e71
--- /dev/null
+++ b/test/v2/celo/FiatTokenCeloV2_2.test.ts
@@ -0,0 +1,159 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { usesOriginalStorageSlotPositions } from "../../helpers/storageSlots.behavior";
+
+import {
+ expectRevert,
+ initializeToVersion,
+ linkLibraryToTokenContract,
+} from "../../helpers";
+import { behavesLikeFiatTokenV2 } from "./../v2.behavior";
+import { behavesLikeFiatTokenV22 } from "./../v2_2.behavior";
+import { initializeOverloadedMethods } from "../FiatTokenV2_2.test";
+import { SignatureBytesType } from "../GasAbstraction/helpers";
+import {
+ AnyFiatTokenV2Instance,
+ FiatTokenCeloV2_2InstanceExtended,
+} from "../../../@types/AnyFiatTokenV2Instance";
+import { FeeCallerChanged } from "../../../@types/generated/FiatTokenCeloV2_2";
+import { HARDHAT_ACCOUNTS } from "../../helpers/constants";
+
+const FiatTokenCeloV2_2 = artifacts.require("FiatTokenCeloV2_2");
+
+// See FiatTokenCeloV2_2#FEE_CALLER_SLOT.
+async function getFeeCaller(fiatTokenCelo: FiatTokenCeloV2_2InstanceExtended) {
+ const feeCaller = await web3.eth.getStorageAt(
+ fiatTokenCelo.address,
+ "0xdca914aef3e4e19727959ebb1e70b58822e2c7b796d303902adc19513fcb4af5"
+ );
+ return web3.utils.toChecksumAddress("0x" + feeCaller.slice(26));
+}
+
+describe("FiatTokenCeloV2_2", () => {
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[9];
+ const lostAndFound = HARDHAT_ACCOUNTS[2];
+ const from = HARDHAT_ACCOUNTS[1];
+ const feeRecipient = HARDHAT_ACCOUNTS[5];
+ const gatewayFeeRecipient = HARDHAT_ACCOUNTS[5];
+ const communityFund = HARDHAT_ACCOUNTS[5];
+ const feeCaller = fiatTokenOwner;
+
+ let fiatTokenCelo: FiatTokenCeloV2_2InstanceExtended;
+
+ const getFiatToken = (
+ signatureBytesType: SignatureBytesType
+ ): (() => AnyFiatTokenV2Instance) => {
+ return () => {
+ initializeOverloadedMethods(fiatTokenCelo, signatureBytesType);
+ return fiatTokenCelo;
+ };
+ };
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenCeloV2_2);
+ });
+
+ beforeEach(async () => {
+ fiatTokenCelo = await FiatTokenCeloV2_2.new();
+ await initializeToVersion(
+ fiatTokenCelo,
+ "2.2",
+ fiatTokenOwner,
+ lostAndFound
+ );
+ // Ensure we set the debit/credit fee caller for testing.
+ await fiatTokenCelo.updateFeeCaller(feeCaller, { from: fiatTokenOwner });
+ });
+
+ describe("initialized FiatTokenCeloV2_2 contract", async () => {
+ await fiatTokenCelo.initializeV2_2([], "CELOUSDC");
+
+ behavesLikeFiatTokenV22(getFiatToken(SignatureBytesType.Unpacked));
+ behavesLikeFiatTokenV2(2.2, getFiatToken(SignatureBytesType.Packed));
+ // Verify that the Celo interface and implementation
+ // has not interfered with existing storage slots.
+ // DEBITED_MUTEX_SLOT should be statically embedded.
+ usesOriginalStorageSlotPositions({
+ Contract: FiatTokenCeloV2_2,
+ version: 2.2,
+ });
+ });
+
+ describe("onlyFeeCaller", () => {
+ const errorMessage = "FiatTokenCeloV2_2: caller is not the fee caller";
+
+ it("should fail to call debitGasFees when caller is not fee caller", async () => {
+ await expectRevert(
+ fiatTokenCelo.debitGasFees(from, 1, { from: from }),
+ errorMessage
+ );
+ });
+
+ it("should fail to call creditGasFees when caller is not fee caller", async () => {
+ await expectRevert(
+ fiatTokenCelo.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ 1,
+ 1,
+ 1,
+ 1,
+ { from: from }
+ ),
+ errorMessage
+ );
+ });
+ });
+
+ describe("feeCaller", () => {
+ it("should return correct feeCaller", async () => {
+ expect(await fiatTokenCelo.feeCaller())
+ .to.equal(feeCaller)
+ .to.equal(
+ web3.utils.toChecksumAddress(await getFeeCaller(fiatTokenCelo))
+ );
+ });
+ });
+
+ describe("updateFeeCaller", () => {
+ it("should fail to update fee caller when sender is not token owner", async () => {
+ const ownableError = "Ownable: caller is not the owner";
+ await expectRevert(
+ fiatTokenCelo.updatePauser(from, { from: from }),
+ ownableError
+ );
+ });
+
+ it("should emit FeeCallerChanged event", async () => {
+ const newFeeCaller = communityFund;
+ const updateFeeCallerEvent = await fiatTokenCelo.updateFeeCaller(
+ newFeeCaller,
+ { from: fiatTokenOwner }
+ );
+
+ const log = updateFeeCallerEvent.logs[0] as Truffle.TransactionLog<
+ FeeCallerChanged
+ >;
+ assert.strictEqual(log.event, "FeeCallerChanged");
+ assert.strictEqual(log.args.newAddress, newFeeCaller);
+ });
+ });
+});
diff --git a/test/v2/celo/FiatTokenFeeAdapterV1.test.ts b/test/v2/celo/FiatTokenFeeAdapterV1.test.ts
new file mode 100644
index 000000000..0e12baee9
--- /dev/null
+++ b/test/v2/celo/FiatTokenFeeAdapterV1.test.ts
@@ -0,0 +1,147 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const FiatTokenFeeAdapterProxy = artifacts.require("FiatTokenFeeAdapterProxy");
+const FiatTokenFeeAdapterV1 = artifacts.require("FiatTokenFeeAdapterV1");
+const FiatTokenCeloV2_2 = artifacts.require("FiatTokenCeloV2_2");
+
+import { BN } from "ethereumjs-util";
+import { FiatTokenFeeAdapterV1Instance } from "../../../@types/generated";
+import { FiatTokenCeloV2_2Instance } from "../../../@types/generated/FiatTokenCeloV2_2";
+import {
+ expectRevert,
+ initializeToVersion,
+ linkLibraryToTokenContract,
+} from "../../helpers";
+import { HARDHAT_ACCOUNTS } from "../../helpers/constants";
+
+describe("FiatTokenFeeAdapterV1", () => {
+ const tokenOwner = HARDHAT_ACCOUNTS[0];
+ const adapterProxyAdmin = HARDHAT_ACCOUNTS[14];
+ const additionalDecimals = 12;
+
+ let feeAdapter: FiatTokenFeeAdapterV1Instance;
+ let fiatToken: FiatTokenCeloV2_2Instance;
+
+ let tokenDecimals: number, adapterDecimals: number;
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenCeloV2_2);
+ });
+
+ beforeEach(async () => {
+ fiatToken = await FiatTokenCeloV2_2.new();
+ await initializeToVersion(fiatToken, "2.2", tokenOwner, tokenOwner);
+
+ tokenDecimals = (await fiatToken.decimals()).toNumber();
+ adapterDecimals = tokenDecimals + additionalDecimals;
+
+ const adapterImplementation = await FiatTokenFeeAdapterV1.new();
+ const adapterProxy = await FiatTokenFeeAdapterProxy.new(
+ adapterImplementation.address
+ );
+ await adapterProxy.changeAdmin(adapterProxyAdmin);
+ feeAdapter = await FiatTokenFeeAdapterV1.at(adapterProxy.address);
+ });
+
+ describe("onlyCeloVm", () => {
+ const errorMessage = "FiatTokenFeeAdapterV1: caller is not VM";
+
+ it("should fail to call debitGasFees when caller is not 0x0", async () => {
+ await feeAdapter.initializeV1(fiatToken.address, adapterDecimals);
+ await expectRevert(feeAdapter.debitGasFees(tokenOwner, 1), errorMessage);
+ });
+
+ it("should fail to call creditGasFees when caller is not 0x0", async () => {
+ await feeAdapter.initializeV1(fiatToken.address, adapterDecimals);
+ await expectRevert(
+ feeAdapter.creditGasFees(
+ tokenOwner,
+ tokenOwner,
+ tokenOwner,
+ tokenOwner,
+ 1,
+ 1,
+ 1,
+ 1
+ ),
+ errorMessage
+ );
+ });
+ });
+
+ describe("initializeV1", () => {
+ const decimalsError =
+ "FiatTokenFeeAdapterV1: Token decimals must be < adapter decimals";
+ const digitDifferenceError =
+ "FiatTokenFeeAdapterV1: Digit difference too large";
+
+ it("should fail to initialize again", async () => {
+ await feeAdapter.initializeV1(fiatToken.address, adapterDecimals);
+ await expectRevert(feeAdapter.initializeV1(fiatToken.address, 1));
+ });
+
+ it("should fail to initialize if digit difference can overflow", async () => {
+ await expectRevert(
+ feeAdapter.initializeV1(
+ fiatToken.address,
+ (await fiatToken.decimals()).add(new BN(100))
+ ),
+ digitDifferenceError
+ );
+ });
+
+ it("should fail when token has same decimals as adapter (redundant)", async () => {
+ await expectRevert(
+ feeAdapter.initializeV1(
+ fiatToken.address,
+ (await fiatToken.decimals()).toNumber()
+ ),
+ decimalsError
+ );
+ });
+
+ it("should fail when token has more decimals than adapter", async () => {
+ await expectRevert(
+ feeAdapter.initializeV1(
+ fiatToken.address,
+ (await fiatToken.decimals()).toNumber() - 1
+ ),
+ decimalsError
+ );
+ });
+ });
+
+ describe("balanceOf", () => {
+ it("should return upscaled balance", async () => {
+ await feeAdapter.initializeV1(fiatToken.address, adapterDecimals);
+
+ const value = 1e6;
+ await fiatToken.configureMinter(tokenOwner, value);
+ await fiatToken.mint(tokenOwner, value, { from: tokenOwner });
+ expect((await fiatToken.balanceOf(tokenOwner)).toNumber()).to.equal(
+ value
+ );
+ expect((await feeAdapter.balanceOf(tokenOwner)).toString()).to.equal(
+ // The adapter should have padded the balance by the additional number
+ // of decimals needed (adapter decimals - token decimals).
+ (value * 10 ** additionalDecimals).toString()
+ );
+ });
+ });
+});
diff --git a/test/v2/celo/MockFiatTokenCeloWithExposedFunctions.test.ts b/test/v2/celo/MockFiatTokenCeloWithExposedFunctions.test.ts
new file mode 100644
index 000000000..35c650c7d
--- /dev/null
+++ b/test/v2/celo/MockFiatTokenCeloWithExposedFunctions.test.ts
@@ -0,0 +1,392 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ expectRevert,
+ initializeToVersion,
+ linkLibraryToTokenContract,
+} from "../../helpers";
+
+const MockFiatTokenCeloWithExposedFunctions = artifacts.require(
+ "MockFiatTokenCeloWithExposedFunctions"
+);
+
+import { MockFiatTokenCeloWithExposedFunctionsInstance } from "../../../@types/generated";
+import {
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_BN,
+ POW_2_255_MINUS1_HEX,
+ ZERO_ADDRESS,
+} from "../../helpers/constants";
+
+describe("MockFiatTokenCeloWithExposedFunctions", () => {
+ // See FiatTokenCeloV2_2#DEBITED_VALUE_SLOT.
+ const debitedValueSlot =
+ "0xd90dccaa76fe7208f2f477143b6adabfeb5d4a5136982894dfc51177fa8eda28";
+
+ const fiatTokenOwner = HARDHAT_ACCOUNTS[0];
+ const lostAndFound = HARDHAT_ACCOUNTS[1];
+ const from = HARDHAT_ACCOUNTS[2];
+ const feeRecipient = HARDHAT_ACCOUNTS[3];
+ const gatewayFeeRecipient = HARDHAT_ACCOUNTS[4];
+ const communityFund = HARDHAT_ACCOUNTS[5];
+ // For these tests, explicitly declare blacklister, master minter, and pauser
+ // variables, even though they'll be initialized to the same address as the owner.
+ const blacklister = fiatTokenOwner;
+ const masterMinter = fiatTokenOwner;
+ const pauser = fiatTokenOwner;
+ const feeCaller = fiatTokenOwner;
+
+ const debitAmount = 1e6;
+
+ const pausedError = "Pausable: paused";
+ const blacklistedError = "Blacklistable: account is blacklisted";
+ const debitInvariantError =
+ "FiatTokenCeloV2_2: Must fully credit before debit";
+ const creditInvariantError =
+ "FiatTokenCeloV2_2: Either no debit or mismatched debit";
+ const additionOverflowError = "SafeMath: addition overflow";
+ const transferFromZeroError = "ERC20: transfer from the zero address";
+
+ let fiatToken: MockFiatTokenCeloWithExposedFunctionsInstance;
+
+ before(async () => {
+ await linkLibraryToTokenContract(MockFiatTokenCeloWithExposedFunctions);
+ });
+
+ beforeEach(async () => {
+ fiatToken = await MockFiatTokenCeloWithExposedFunctions.new();
+ await initializeToVersion(fiatToken, "2.2", fiatTokenOwner, lostAndFound);
+
+ // Configure some minter allowance (1M) ahead of time.
+ const mintAllowance = 1000000e6;
+ await fiatToken.configureMinter(feeCaller, mintAllowance, {
+ from: masterMinter,
+ });
+ // Set the from address up with some funding.
+ await fiatToken.mint(from, 1000e6, { from: feeCaller });
+
+ await fiatToken.updateFeeCaller(feeCaller);
+ });
+
+ describe("debitGasFees", () => {
+ it("should debit with correct fee caller address", async () => {
+ const balanceFrom = await fiatToken.balanceOf(from);
+
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ expect((await fiatToken.balanceOf(from)).toNumber()).to.equal(
+ balanceFrom.toNumber() - debitAmount
+ );
+ expect((await fiatToken.balanceOf(ZERO_ADDRESS)).toNumber()).to.equal(
+ debitAmount
+ );
+ expect(
+ web3.utils.hexToNumber(
+ await web3.eth.getStorageAt(fiatToken.address, debitedValueSlot)
+ )
+ )
+ .to.equal(debitAmount)
+ .to.equal((await fiatToken.internal_debitedValue()).toNumber());
+ });
+
+ it("should fail to debit again with ongoing debit", async () => {
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ await expectRevert(
+ fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }),
+ debitInvariantError
+ );
+ });
+
+ it("should fail to debit from the zero address", async () => {
+ await expectRevert(
+ fiatToken.debitGasFees(ZERO_ADDRESS, debitAmount, { from: feeCaller }),
+ transferFromZeroError
+ );
+ });
+
+ it("should fail when contract is paused", async () => {
+ await fiatToken.pause({ from: pauser });
+ await expectRevert(
+ fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }),
+ pausedError
+ );
+ });
+
+ it("should fail when `from` is blacklisted", async () => {
+ await fiatToken.blacklist(from, { from: blacklister });
+ await expectRevert(
+ fiatToken.debitGasFees(from, debitAmount, { from: feeCaller }),
+ blacklistedError
+ );
+ });
+ });
+
+ describe("creditGasFees", () => {
+ const tipTxFee = 1e5;
+ // Invariant: the network does not actually make use of the gateway fee.
+ const gatewayFee = 0;
+ const baseTxFee = 3e5;
+
+ // The original debit always equals refund + tipTxFee + gatewayFee + baseTxFee.
+ const refund: number = debitAmount - tipTxFee - gatewayFee - baseTxFee;
+
+ it("should credit after debit with correct fee caller address", async () => {
+ const fromBalancePre = (await fiatToken.balanceOf(from)).toNumber();
+ const feeRecipientBalancePre = (
+ await fiatToken.balanceOf(feeRecipient)
+ ).toNumber();
+ const gatewayFeeRecipientBalancePre = (
+ await fiatToken.balanceOf(gatewayFeeRecipient)
+ ).toNumber();
+ const communityFundBalancePre = (
+ await fiatToken.balanceOf(communityFund)
+ ).toNumber();
+
+ // In practice, this debiting and crediting sequence should always be atomic
+ // within the Celo VM core state transition code itself. See L481 and L517 at
+ // https://github.com/celo-org/celo-blockchain/blob/3808c45addf56cf547581599a1cb059bc4ae5089/core/state_transition.go#L426-L526.
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ expect(
+ web3.utils.hexToNumber(
+ await web3.eth.getStorageAt(fiatToken.address, debitedValueSlot)
+ )
+ )
+ .to.equal(debitAmount)
+ .to.equal((await fiatToken.internal_debitedValue()).toNumber());
+
+ await fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ refund,
+ tipTxFee,
+ gatewayFee,
+ baseTxFee,
+ { from: feeCaller }
+ );
+ expect(
+ web3.utils.hexToNumber(
+ await web3.eth.getStorageAt(fiatToken.address, debitedValueSlot)
+ )
+ )
+ .to.equal(0)
+ .to.equal((await fiatToken.internal_debitedValue()).toNumber());
+ const fromBalancePost = (await fiatToken.balanceOf(from)).toNumber();
+ const feeRecipientBalancePost = (
+ await fiatToken.balanceOf(feeRecipient)
+ ).toNumber();
+ const gatewayFeeRecipientBalancePost = (
+ await fiatToken.balanceOf(gatewayFeeRecipient)
+ ).toNumber();
+ const communityFundBalancePost = (
+ await fiatToken.balanceOf(communityFund)
+ ).toNumber();
+
+ expect(fromBalancePost).to.equal(fromBalancePre - debitAmount + refund);
+ expect(feeRecipientBalancePost).to.equal(
+ feeRecipientBalancePre + tipTxFee
+ );
+ expect(gatewayFeeRecipientBalancePost).to.equal(
+ gatewayFeeRecipientBalancePre + gatewayFee
+ );
+ expect(communityFundBalancePost).to.equal(
+ communityFundBalancePre + baseTxFee
+ );
+ });
+
+ it("should fail to credit with mismatched debit amount", async () => {
+ // (_debitedValue != refund + tipTxFee + gatewayFee + baseTxFee)
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ await expectRevert(
+ fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ // Mess with the refund here to break the invariant.
+ refund - 1,
+ tipTxFee,
+ gatewayFee,
+ baseTxFee,
+ { from: feeCaller }
+ ),
+ creditInvariantError
+ );
+ });
+
+ it("should fail to credit with no ongoing debit", async () => {
+ // (_debitedValue = 0)
+ await expectRevert(
+ fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ refund,
+ tipTxFee,
+ gatewayFee,
+ baseTxFee,
+ { from: feeCaller }
+ ),
+ creditInvariantError
+ );
+ });
+
+ it("should fail to credit when total amount can overflow (SafeMath)", async () => {
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ await expectRevert(
+ fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ MAX_UINT256_BN,
+ MAX_UINT256_BN,
+ MAX_UINT256_BN,
+ MAX_UINT256_BN,
+ { from: feeCaller }
+ ),
+ additionOverflowError
+ );
+ });
+
+ it("should fail when contract is paused", async () => {
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ await fiatToken.pause({ from: pauser });
+ await expectRevert(
+ fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ refund,
+ tipTxFee,
+ gatewayFee,
+ baseTxFee,
+ { from: feeCaller }
+ ),
+ pausedError
+ );
+ });
+
+ it("should fail when `from` is blacklisted", async () => {
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ await fiatToken.blacklist(from, { from: blacklister });
+ await expectRevert(
+ fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ refund,
+ tipTxFee,
+ gatewayFee,
+ baseTxFee,
+ { from: feeCaller }
+ ),
+ blacklistedError
+ );
+ });
+
+ it("should fail when `feeRecipient` is blacklisted", async () => {
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ await fiatToken.blacklist(feeRecipient, { from: blacklister });
+ await expectRevert(
+ fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ refund,
+ tipTxFee,
+ gatewayFee,
+ baseTxFee,
+ { from: feeCaller }
+ ),
+ blacklistedError
+ );
+ });
+
+ it("should fail when `communityFund` is blacklisted", async () => {
+ await fiatToken.debitGasFees(from, debitAmount, { from: feeCaller });
+ await fiatToken.blacklist(communityFund, { from: blacklister });
+ await expectRevert(
+ fiatToken.creditGasFees(
+ from,
+ feeRecipient,
+ gatewayFeeRecipient,
+ communityFund,
+ refund,
+ tipTxFee,
+ gatewayFee,
+ baseTxFee,
+ { from: feeCaller }
+ ),
+ blacklistedError
+ );
+ });
+ });
+
+ describe("_transferReservedGas", () => {
+ const zeroGasError = "FiatTokenCeloV2_2: Must reserve > 0 gas";
+ const balanceExceededError = "FiatTokenV2_2: Balance exceeds (2^255 - 1)";
+ const balanceInsufficientError = "ERC20: transfer amount exceeds balance";
+
+ const validTransferAmt = 1e4;
+
+ it("should fail when 0 reserved gas is requested", async () => {
+ await expectRevert(
+ fiatToken.internal_transferReservedGas(from, ZERO_ADDRESS, 0, {
+ from: feeCaller,
+ }),
+ zeroGasError
+ );
+ });
+
+ it("should fail when _to's balance will exceed 2^255 - 1", async () => {
+ // Granting enough balance to feeCaller
+ await fiatToken.internal_setBalance(feeCaller, POW_2_255_MINUS1_HEX);
+ await fiatToken.internal_setBalance(from, validTransferAmt);
+
+ await expectRevert(
+ fiatToken.internal_transferReservedGas(
+ feeCaller,
+ from,
+ POW_2_255_MINUS1_HEX,
+ { from: feeCaller }
+ ),
+ balanceExceededError
+ );
+ });
+
+ it("should fail when _from's balance < _value", async () => {
+ await expectRevert(
+ fiatToken.internal_transferReservedGas(
+ feeCaller,
+ from,
+ (await fiatToken.balanceOf(feeCaller)).toNumber() + 100,
+ {
+ from: feeCaller,
+ }
+ ),
+ balanceInsufficientError
+ );
+ });
+ });
+});
diff --git a/test/v2/celo/MockFiatTokenFeeAdapterWithExposedFunctions.test.ts b/test/v2/celo/MockFiatTokenFeeAdapterWithExposedFunctions.test.ts
new file mode 100644
index 000000000..74e4aab01
--- /dev/null
+++ b/test/v2/celo/MockFiatTokenFeeAdapterWithExposedFunctions.test.ts
@@ -0,0 +1,246 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const MockFiatTokenFeeAdapterWithExposedFunctions = artifacts.require(
+ "MockFiatTokenFeeAdapterWithExposedFunctions"
+);
+const FiatTokenCeloV2_2 = artifacts.require("FiatTokenCeloV2_2");
+
+import { BN } from "ethereumjs-util";
+import { MockFiatTokenFeeAdapterWithExposedFunctionsInstance } from "../../../@types/generated";
+import { FiatTokenCeloV2_2Instance } from "../../../@types/generated/FiatTokenCeloV2_2";
+import {
+ expectRevert,
+ initializeToVersion,
+ linkLibraryToTokenContract,
+} from "../../helpers";
+import {
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_BN,
+ POW_2_255_MINUS1_HEX,
+ ZERO_ADDRESS,
+} from "../../helpers/constants";
+
+describe("MockFiatTokenFeeAdapterWithExposedFunctions", () => {
+ const vm = HARDHAT_ACCOUNTS[0];
+ // BN doesn't play nicely with scientific notation, so use string constructors instead.
+ // This debit amount will be downscaled appropriately to the token.
+ const debitAmount = new BN("1000000000000000000"); // 1e18
+ const mintAmount = new BN("1000000000000000000000000"); // 1e24
+
+ const owner = HARDHAT_ACCOUNTS[1];
+ const from = HARDHAT_ACCOUNTS[2];
+
+ const additionalDecimals = 12;
+
+ let feeAdapter: MockFiatTokenFeeAdapterWithExposedFunctionsInstance;
+ let fiatToken: FiatTokenCeloV2_2Instance;
+
+ let tokenDecimals: number, adapterDecimals: number;
+
+ before(async () => {
+ await linkLibraryToTokenContract(FiatTokenCeloV2_2);
+ });
+
+ beforeEach(async () => {
+ fiatToken = await FiatTokenCeloV2_2.new();
+ // This initializes with 6 decimals.
+ await initializeToVersion(fiatToken, "2.2", owner, owner);
+ await fiatToken.configureMinter(owner, POW_2_255_MINUS1_HEX, {
+ from: owner,
+ });
+ // Set up some funds ahead of time.
+ await fiatToken.mint(from, mintAmount, { from: owner });
+
+ tokenDecimals = (await fiatToken.decimals()).toNumber();
+ adapterDecimals = tokenDecimals + additionalDecimals;
+
+ // Set up the adapter.
+ feeAdapter = await MockFiatTokenFeeAdapterWithExposedFunctions.new();
+ await feeAdapter.initializeV1(fiatToken.address, adapterDecimals);
+ await feeAdapter.setVmCallerAddress(vm);
+
+ // Make sure we can actually start the call chain through the adapter.
+ await fiatToken.updateFeeCaller(feeAdapter.address, { from: owner });
+ });
+
+ describe("_upscale", () => {
+ it("should return proper upscaled value", async () => {
+ const valueUpscaled = await feeAdapter.internal_upscale(1 ** 0);
+ expect(valueUpscaled.toNumber()).to.equal(10 ** additionalDecimals);
+ });
+
+ it("should revert upscaling when overflowed", async () => {
+ await expectRevert(
+ feeAdapter.internal_upscale(MAX_UINT256_BN),
+ "SafeMath: multiplication overflow"
+ );
+ });
+ });
+
+ describe("_downscale", () => {
+ it("should return proper downscaled value", async () => {
+ // Web3JS doesn't play nice with very large raw number variables;
+ // passing a nonstring here will result in an error.
+ const value = (10 ** adapterDecimals).toString();
+ const valueDownscaled = await feeAdapter.internal_downscale(value);
+ expect(valueDownscaled.toNumber()).to.equal(
+ 10 ** (adapterDecimals - additionalDecimals)
+ );
+ });
+
+ it("should return zero if value is small enough", async () => {
+ // Since this value has less additional decimals added, it should
+ // be stripped down to 0.
+ const value = 10 ** (additionalDecimals - 1);
+ expect((await feeAdapter.internal_downscale(value)).toNumber()).to.equal(
+ 0
+ );
+ });
+ });
+
+ describe("debitGasFees", () => {
+ it("should debit with correct fee caller address", async () => {
+ const balanceInitialFrom = await fiatToken.balanceOf(from);
+ const balanceInitialFromUpscaled = await feeAdapter.balanceOf(from);
+
+ const debitAmountDownscaled = debitAmount.divRound(
+ new BN(10).pow(new BN(additionalDecimals))
+ );
+
+ await feeAdapter.debitGasFees(from, debitAmount, { from: vm });
+ // Triple-compare: both contracts store the true debited value.
+ expect((await feeAdapter.internal_debitedValue()).toString())
+ .to.equal(debitAmountDownscaled.toString())
+ .to.equal(
+ web3.utils.hexToNumberString(
+ await web3.eth.getStorageAt(
+ fiatToken.address,
+ // FiatTokenCeloV2_2#DEBITED_VALUE_SLOT Keccak256 hash.
+ "0xd90dccaa76fe7208f2f477143b6adabfeb5d4a5136982894dfc51177fa8eda28"
+ )
+ )
+ );
+
+ // Assert balances affected.
+ expect((await feeAdapter.balanceOf(from)).toString()).to.equal(
+ balanceInitialFromUpscaled.sub(debitAmount).toString()
+ );
+ expect((await fiatToken.balanceOf(from)).toString()).to.equal(
+ balanceInitialFrom.sub(debitAmountDownscaled).toString()
+ );
+ expect((await fiatToken.balanceOf(ZERO_ADDRESS)).toString()).to.equal(
+ debitAmountDownscaled.toString()
+ );
+ });
+
+ it("should fail to debit again", async () => {
+ await feeAdapter.debitGasFees(from, debitAmount, {
+ from: vm,
+ });
+ await expectRevert(
+ feeAdapter.debitGasFees(from, debitAmount, {
+ from: vm,
+ }),
+ "FiatTokenFeeAdapterV1: Must fully credit before debit"
+ );
+ });
+ });
+
+ describe("creditGasFees", () => {
+ it("should should credit with no rounding error after debit", async () => {
+ const debitAmount = new BN("200000000000000000000000");
+ const refund = new BN("100000000000000000000000");
+ const tipTxFee = new BN("90000000000000000000000");
+ const baseTxFee = new BN("10000000000000000000000");
+
+ const fromBalancePre = await feeAdapter.balanceOf(from);
+ await feeAdapter.debitGasFees(from, debitAmount, { from: vm });
+ await feeAdapter.creditGasFees(
+ from,
+ from,
+ from,
+ from,
+ refund,
+ tipTxFee,
+ 0,
+ baseTxFee,
+ { from: vm }
+ );
+ const fromBalancePost = await feeAdapter.balanceOf(from);
+
+ expect(fromBalancePre.toString()).to.equal(fromBalancePost.toString());
+ });
+
+ it("should should credit properly with rounding error after debit", async () => {
+ const debitAmount = new BN("1234560000000000000000");
+ const refund = new BN("1000009999999999999999"); // Trailing 9s will be dropped.
+ const tipTxFee = new BN("234550000000000000001"); // Trailing 1 will be dropped.
+ const baseTxFee = new BN("1"); // This will be downscaled to 0.
+
+ const fromBalancePre = await feeAdapter.balanceOf(from);
+ await feeAdapter.debitGasFees(from, debitAmount, { from: vm });
+ // Send all back to the from address for testing.
+ await feeAdapter.creditGasFees(
+ from,
+ from,
+ from,
+ from,
+ refund,
+ tipTxFee,
+ 0,
+ baseTxFee,
+ { from: vm }
+ );
+ const fromBalancePost = await feeAdapter.balanceOf(from);
+
+ // There should be no change in amounts even after all the scaling operations.
+ expect(fromBalancePre.toString()).to.equal(fromBalancePost.toString());
+ });
+
+ it("should do nothing if debited is exactly 0", async () => {
+ const balanceInitialFrom = await fiatToken.balanceOf(from);
+
+ await feeAdapter.creditGasFees(from, from, from, from, 1, 1, 1, 1, {
+ from: vm,
+ });
+ expect((await fiatToken.balanceOf(from)).toString()).to.equal(
+ balanceInitialFrom.toString()
+ );
+ });
+
+ it("should fail to credit more than debited", async () => {
+ await feeAdapter.debitGasFees(from, debitAmount, {
+ from: vm,
+ });
+ await expectRevert(
+ feeAdapter.creditGasFees(
+ from,
+ from,
+ from,
+ from,
+ debitAmount,
+ debitAmount,
+ debitAmount,
+ debitAmount
+ ),
+ "FiatTokenFeeAdapterV1: Cannot credit more than debited"
+ );
+ });
+ });
+});
diff --git a/test/v2/safeAllowance.behavior.ts b/test/v2/safeAllowance.behavior.ts
index 911c87c7d..40f49a584 100644
--- a/test/v2/safeAllowance.behavior.ts
+++ b/test/v2/safeAllowance.behavior.ts
@@ -1,16 +1,39 @@
-import { FiatTokenV2Instance } from "../../@types/generated";
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { AnyFiatTokenV2Instance } from "../../@types/AnyFiatTokenV2Instance";
import { Approval } from "../../@types/generated/FiatTokenV2";
import { expectRevert } from "../helpers";
-import { MAX_UINT256 } from "../helpers/constants";
+import { MAX_UINT256_HEX, HARDHAT_ACCOUNTS } from "../helpers/constants";
export function hasSafeAllowance(
- getFiatToken: () => FiatTokenV2Instance,
- fiatTokenOwner: string,
- accounts: Truffle.Accounts
+ version: number,
+ getFiatToken: () => AnyFiatTokenV2Instance
): void {
describe("safe allowance", () => {
- let fiatToken: FiatTokenV2Instance;
- const [alice, bob] = accounts;
+ const [alice, bob] = HARDHAT_ACCOUNTS;
+
+ let fiatToken: AnyFiatTokenV2Instance;
+ let fiatTokenOwner: string;
+
+ before(async () => {
+ fiatTokenOwner = await getFiatToken().owner();
+ });
beforeEach(() => {
fiatToken = getFiatToken();
@@ -55,7 +78,7 @@ export function hasSafeAllowance(
});
await expectRevert(
- fiatToken.increaseAllowance(bob, MAX_UINT256, {
+ fiatToken.increaseAllowance(bob, MAX_UINT256_HEX, {
from: alice,
}),
"addition overflow"
@@ -73,26 +96,57 @@ export function hasSafeAllowance(
);
});
- it("reverts if either the owner or the spender is blacklisted", async () => {
- // owner is blacklisted
- await fiatToken.blacklist(alice, { from: fiatTokenOwner });
+ if (version < 2.2) {
+ it("reverts if either the owner or the spender is blacklisted", async () => {
+ // owner is blacklisted
+ await fiatToken.blacklist(alice, { from: fiatTokenOwner });
- // try to increase allowance
- await expectRevert(
- fiatToken.increaseAllowance(bob, 1, { from: alice }),
- "account is blacklisted"
- );
+ // try to increase allowance
+ await expectRevert(
+ fiatToken.increaseAllowance(bob, 1, { from: alice }),
+ "account is blacklisted"
+ );
- // spender is blacklisted
- await fiatToken.unBlacklist(alice, { from: fiatTokenOwner });
- await fiatToken.blacklist(bob, { from: fiatTokenOwner });
+ // spender is blacklisted
+ await fiatToken.unBlacklist(alice, { from: fiatTokenOwner });
+ await fiatToken.blacklist(bob, { from: fiatTokenOwner });
- // try to increase allowance
- await expectRevert(
- fiatToken.increaseAllowance(bob, 1, { from: alice }),
- "account is blacklisted"
- );
- });
+ // try to increase allowance
+ await expectRevert(
+ fiatToken.increaseAllowance(bob, 1, { from: alice }),
+ "account is blacklisted"
+ );
+ });
+ } else {
+ // version >= 2.2
+
+ it("increases allowance normally when the owner or the spender is blacklisted", async () => {
+ // owner is blacklisted
+ await fiatToken.blacklist(alice, { from: fiatTokenOwner });
+
+ // try to increase allowance
+ await fiatToken.increaseAllowance(bob, 10e6, {
+ from: alice,
+ });
+ // check that allowance has increased
+ expect((await fiatToken.allowance(alice, bob)).toNumber()).to.equal(
+ 10e6
+ );
+
+ // spender is blacklisted
+ await fiatToken.unBlacklist(alice, { from: fiatTokenOwner });
+ await fiatToken.blacklist(bob, { from: fiatTokenOwner });
+
+ // try to increase allowance
+ await fiatToken.increaseAllowance(bob, 5e6, {
+ from: alice,
+ });
+ // check that allowance has increased
+ expect((await fiatToken.allowance(alice, bob)).toNumber()).to.equal(
+ 15e6
+ );
+ });
+ }
});
describe("decreaseAllowance", () => {
@@ -146,7 +200,7 @@ export function hasSafeAllowance(
// it catches that the given decrement is greater than the current
// allowance
await expectRevert(
- fiatToken.decreaseAllowance(bob, MAX_UINT256, {
+ fiatToken.decreaseAllowance(bob, MAX_UINT256_HEX, {
from: alice,
}),
"decreased allowance below zero"
@@ -164,26 +218,53 @@ export function hasSafeAllowance(
);
});
- it("reverts if either the owner or the spender is blacklisted", async () => {
- // owner is blacklisted
- await fiatToken.blacklist(alice, { from: fiatTokenOwner });
+ if (version < 2.2) {
+ it("reverts if either the owner or the spender is blacklisted", async () => {
+ // owner is blacklisted
+ await fiatToken.blacklist(alice, { from: fiatTokenOwner });
- // try to decrease allowance
- await expectRevert(
- fiatToken.decreaseAllowance(bob, 1, { from: alice }),
- "account is blacklisted"
- );
+ // try to decrease allowance
+ await expectRevert(
+ fiatToken.decreaseAllowance(bob, 1, { from: alice }),
+ "account is blacklisted"
+ );
- // spender is blacklisted
- await fiatToken.unBlacklist(alice, { from: fiatTokenOwner });
- await fiatToken.blacklist(bob, { from: fiatTokenOwner });
+ // spender is blacklisted
+ await fiatToken.unBlacklist(alice, { from: fiatTokenOwner });
+ await fiatToken.blacklist(bob, { from: fiatTokenOwner });
- // try to decrease allowance
- await expectRevert(
- fiatToken.decreaseAllowance(bob, 1, { from: alice }),
- "account is blacklisted"
- );
- });
+ // try to decrease allowance
+ await expectRevert(
+ fiatToken.decreaseAllowance(bob, 1, { from: alice }),
+ "account is blacklisted"
+ );
+ });
+ } else {
+ // version >= 2.2
+
+ it("decreases allowance normally when the owner or the spender is blacklisted", async () => {
+ // owner is blacklisted
+ await fiatToken.blacklist(alice, { from: fiatTokenOwner });
+
+ // try to decrease allowance
+ await fiatToken.decreaseAllowance(bob, 2e6, { from: alice });
+ // check that allowance has decreased
+ expect((await fiatToken.allowance(alice, bob)).toNumber()).to.equal(
+ 8e6
+ );
+
+ // spender is blacklisted
+ await fiatToken.unBlacklist(alice, { from: fiatTokenOwner });
+ await fiatToken.blacklist(bob, { from: fiatTokenOwner });
+
+ // try to decrease allowance
+ await fiatToken.decreaseAllowance(bob, 2e6, { from: alice });
+ // check that allowance has decreased
+ expect((await fiatToken.allowance(alice, bob)).toNumber()).to.equal(
+ 6e6
+ );
+ });
+ }
});
});
}
diff --git a/test/v2/v2.behavior.ts b/test/v2/v2.behavior.ts
new file mode 100644
index 000000000..d3262cafc
--- /dev/null
+++ b/test/v2/v2.behavior.ts
@@ -0,0 +1,92 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { behavesLikeRescuable } from "../v1.1/Rescuable.behavior";
+import {
+ MockERC1271WalletInstance,
+ RescuableInstance,
+} from "../../@types/generated";
+import { AnyFiatTokenV2Instance } from "../../@types/AnyFiatTokenV2Instance";
+import { hasSafeAllowance } from "./safeAllowance.behavior";
+import { hasGasAbstraction } from "./GasAbstraction/GasAbstraction.behavior";
+import {
+ SignatureBytesType,
+ TestParams,
+ WalletType,
+ makeDomainSeparator,
+} from "./GasAbstraction/helpers";
+import { expectRevert } from "../helpers";
+import { testTransferWithMultipleAuthorizations } from "./GasAbstraction/testTransferWithMultipleAuthorizations";
+
+const MockERC1271Wallet = artifacts.require("MockERC1271Wallet");
+
+export function behavesLikeFiatTokenV2(
+ version: number,
+ getFiatToken: () => AnyFiatTokenV2Instance
+): void {
+ let domainSeparator: string;
+ let fiatTokenOwner: string;
+
+ beforeEach(async () => {
+ // owner() is run here instead of once in a before() hook, since the contract
+ // must be instantiated by a previously defined beforeEach() hook before
+ // calling owner()
+ fiatTokenOwner = await getFiatToken().owner();
+
+ domainSeparator = makeDomainSeparator(
+ "USDC",
+ "2",
+ await web3.eth.getChainId(),
+ getFiatToken().address
+ );
+ });
+
+ behavesLikeRescuable(getFiatToken as () => RescuableInstance);
+
+ it("has the expected domain separator", async () => {
+ expect(await getFiatToken().DOMAIN_SEPARATOR()).to.equal(domainSeparator);
+ });
+
+ hasSafeAllowance(version, getFiatToken);
+
+ const testParams: TestParams = {
+ version,
+ getFiatToken,
+ getDomainSeparator: () => domainSeparator,
+ getERC1271Wallet,
+ signerWalletType: WalletType.EOA,
+ signatureBytesType: SignatureBytesType.Unpacked,
+ };
+
+ hasGasAbstraction(testParams);
+
+ testTransferWithMultipleAuthorizations(testParams);
+
+ it("disallows calling initializeV2 twice", async () => {
+ // It was called once in beforeEach. Try to call again.
+ await expectRevert(
+ getFiatToken().initializeV2("Not USDC", { from: fiatTokenOwner })
+ );
+ });
+}
+
+export async function getERC1271Wallet(
+ owner: string
+): Promise {
+ return await MockERC1271Wallet.new(owner);
+}
diff --git a/test/v2/v2_2.behavior.ts b/test/v2/v2_2.behavior.ts
new file mode 100644
index 000000000..080410a65
--- /dev/null
+++ b/test/v2/v2_2.behavior.ts
@@ -0,0 +1,202 @@
+/**
+ * Copyright 2024 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import BN from "bn.js";
+import crypto from "crypto";
+import {
+ AnyFiatTokenV2Instance,
+ FiatTokenV2_2InstanceExtended,
+} from "../../@types/AnyFiatTokenV2Instance";
+import { expectRevert, hexStringFromBuffer } from "../helpers";
+import {
+ ACCOUNTS_AND_KEYS,
+ HARDHAT_ACCOUNTS,
+ MAX_UINT256_HEX,
+ POW_2_255_BN,
+} from "../helpers/constants";
+import { getERC1271Wallet } from "./v2.behavior";
+import { hasGasAbstraction } from "./GasAbstraction/GasAbstraction.behavior";
+import {
+ SignatureBytesType,
+ WalletType,
+ makeDomainSeparator,
+ prepareSignature,
+ signTransferAuthorization,
+ signReceiveAuthorization,
+} from "./GasAbstraction/helpers";
+
+export function behavesLikeFiatTokenV22(
+ getFiatToken: () => AnyFiatTokenV2Instance
+): void {
+ const [minter, arbitraryAccount] = HARDHAT_ACCOUNTS.slice(3);
+
+ let fiatTokenOwner: string;
+ let domainSeparator: string;
+ let fiatToken: FiatTokenV2_2InstanceExtended;
+
+ before(async () => {
+ fiatTokenOwner = await getFiatToken().owner();
+ });
+
+ beforeEach(async () => {
+ fiatToken = getFiatToken() as FiatTokenV2_2InstanceExtended;
+ domainSeparator = makeDomainSeparator(
+ "USDC",
+ "2",
+ await web3.eth.getChainId(),
+ fiatToken.address
+ );
+ });
+
+ const v22TestParams = {
+ version: 2.2,
+ getFiatToken,
+ getDomainSeparator: () => domainSeparator,
+ getERC1271Wallet,
+ };
+
+ // Test gas abstraction functionalities with both EOA and AA wallets
+ hasGasAbstraction({
+ ...v22TestParams,
+ signerWalletType: WalletType.EOA,
+ signatureBytesType: SignatureBytesType.Packed,
+ });
+ hasGasAbstraction({
+ ...v22TestParams,
+ signerWalletType: WalletType.AA,
+ signatureBytesType: SignatureBytesType.Packed,
+ });
+
+ // Additional negative test cases.
+ describe("will trigger exceeded 2^255 balance error", () => {
+ const incrementAmount = 1000;
+ const recipient = arbitraryAccount;
+ const errorMessage = "FiatTokenV2_2: Balance exceeds (2^255 - 1)";
+
+ beforeEach(async () => {
+ const recipientInitialBalance = POW_2_255_BN.sub(new BN(incrementAmount));
+ await fiatToken.configureMinter(minter, POW_2_255_BN, {
+ from: fiatTokenOwner,
+ });
+ await fiatToken.mint(recipient, recipientInitialBalance, {
+ from: minter,
+ });
+ expect((await fiatToken.balanceOf(recipient)).eq(recipientInitialBalance))
+ .to.be.true;
+ });
+
+ it("should fail to mint to recipient if balance will exceed 2^255", async () => {
+ await expectRevert(
+ fiatToken.mint(recipient, incrementAmount, { from: minter }),
+ errorMessage
+ );
+ });
+
+ it("should fail to transfer to recipient if balance will exceed 2^255", async () => {
+ await fiatToken.mint(minter, incrementAmount, { from: minter });
+ await expectRevert(
+ fiatToken.transfer(recipient, incrementAmount, { from: minter }),
+ errorMessage
+ );
+ });
+
+ it("should fail call transferFrom to recipient if balance will exceed 2^255", async () => {
+ await fiatToken.mint(minter, incrementAmount, { from: minter });
+ await fiatToken.approve(arbitraryAccount, incrementAmount, {
+ from: minter,
+ });
+
+ await expectRevert(
+ fiatToken.transferFrom(minter, recipient, incrementAmount, {
+ from: arbitraryAccount,
+ }),
+ errorMessage
+ );
+ });
+
+ context("EIP3009", () => {
+ const signer = ACCOUNTS_AND_KEYS[0];
+ const from = signer.address;
+ const to = recipient;
+ const value = incrementAmount;
+ const validAfter = 0;
+ const validBefore = MAX_UINT256_HEX;
+ const nonce = hexStringFromBuffer(crypto.randomBytes(32));
+
+ beforeEach(async () => {
+ await fiatToken.mint(signer.address, incrementAmount, {
+ from: minter,
+ });
+ });
+
+ it("should fail to call transferWithAuthorization to recipient if balance will exceed 2^255", async () => {
+ const signature = signTransferAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ signer.key
+ );
+
+ await expectRevert(
+ fiatToken.transferWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, SignatureBytesType.Packed),
+ { from: to }
+ ),
+ errorMessage
+ );
+ });
+
+ it("should fail to call receiveWithAuthorization to recipient if balance will exceed 2^255", async () => {
+ const signature = signReceiveAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ domainSeparator,
+ signer.key
+ );
+
+ await expectRevert(
+ fiatToken.receiveWithAuthorization(
+ from,
+ to,
+ value,
+ validAfter,
+ validBefore,
+ nonce,
+ ...prepareSignature(signature, SignatureBytesType.Packed),
+ { from: to }
+ ),
+ errorMessage
+ );
+ });
+ });
+ });
+}
diff --git a/truffle-config.js b/truffle-config.js
deleted file mode 100644
index 9145487eb..000000000
--- a/truffle-config.js
+++ /dev/null
@@ -1,70 +0,0 @@
-process.env.TS_NODE_FILES = "true";
-require("ts-node/register/transpile-only");
-// Fix Typescript callsite reporting
-Object.defineProperty(Error, "prepareStackTrace", { writable: false });
-
-const HDWalletProvider = require("@truffle/hdwallet-provider");
-const fs = require("fs");
-const path = require("path");
-
-// Read config file if it exists
-let config = { MNEMONIC: "", INFURA_KEY: "" };
-if (fs.existsSync(path.join(__dirname, "config.js"))) {
- config = require("./config.js");
-}
-
-module.exports = {
- compilers: {
- solc: {
- version: "0.6.12",
- settings: {
- optimizer: {
- enabled: true,
- runs: 10000000,
- },
- },
- },
- },
- networks: {
- development: {
- host: "localhost",
- port: 8545,
- network_id: "*", // Match any network id
- },
- local_testnet: {
- host: "ganache",
- port: 8545,
- network_id: "*", // Match any network id
- },
- mainnet: {
- provider: infuraProvider("mainnet"),
- network_id: 1,
- },
- ropsten: {
- provider: infuraProvider("ropsten"),
- network_id: 3,
- },
- },
- mocha: {
- timeout: 10000, // prevents tests from failing when pc is under heavy load
- reporter: "Spec",
- },
- plugins: ["solidity-coverage"],
-};
-
-function infuraProvider(network) {
- return () => {
- if (!config.MNEMONIC) {
- console.error("A valid MNEMONIC must be provided in config.js");
- process.exit(1);
- }
- if (!config.INFURA_KEY) {
- console.error("A valid INFURA_KEY must be provided in config.js");
- process.exit(1);
- }
- return new HDWalletProvider(
- config.MNEMONIC,
- `https://${network}.infura.io/v3/${config.INFURA_KEY}`
- );
- };
-}
diff --git a/tsconfig.json b/tsconfig.json
index 230509337..57145e2b9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -19,5 +19,5 @@
"target": "ES2019"
},
"include": ["**/*.ts", "*.ts"],
- "exclude": ["node_modules", "build"]
+ "exclude": ["node_modules"]
}
diff --git a/utils.js b/utils.js
new file mode 100644
index 000000000..b4ee3a5c5
--- /dev/null
+++ b/utils.js
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2023 Circle Internet Group, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const _ = require("lodash");
+const fs = require("fs");
+const web3 = require("web3");
+
+/**
+ * Helper function to read the blacklist file.
+ * @param {string} blacklistFilePath the filepath to the blacklist file.
+ * @returns {string[]} the list of addresses in the file.
+ */
+function readBlacklistFile(blacklistFilePath) {
+ if (!fs.existsSync(blacklistFilePath)) {
+ throw new Error(`'${blacklistFilePath}' does not exist!`);
+ }
+ let addresses = JSON.parse(fs.readFileSync(blacklistFilePath));
+ addresses = _.uniqBy(addresses, (a) => a.toLowerCase()); // Deduplicate any addresses in the file
+
+ // Validate that addresses' integrity
+ for (const address of addresses) {
+ if (!web3.utils.isAddress(address)) {
+ throw new Error(
+ `Address '${address}' in '${blacklistFilePath}' is not valid address!`
+ );
+ }
+ }
+ return addresses;
+}
+
+module.exports = { readBlacklistFile };
diff --git a/validate/FiatTokenProxy.etherscan b/validate/FiatTokenProxy.etherscan
deleted file mode 100644
index 10c84dded..000000000
--- a/validate/FiatTokenProxy.etherscan
+++ /dev/null
@@ -1,329 +0,0 @@
-pragma solidity ^0.4.24;
-
-// File: zos-lib/contracts/upgradeability/Proxy.sol
-
-/**
- * @title Proxy
- * @dev Implements delegation of calls to other contracts, with proper
- * forwarding of return values and bubbling of failures.
- * It defines a fallback function that delegates all calls to the address
- * returned by the abstract _implementation() internal function.
- */
-contract Proxy {
- /**
- * @dev Fallback function.
- * Implemented entirely in `_fallback`.
- */
- function () payable external {
- _fallback();
- }
-
- /**
- * @return The Address of the implementation.
- */
- function _implementation() internal view returns (address);
-
- /**
- * @dev Delegates execution to an implementation contract.
- * This is a low level function that doesn't return to its internal call site.
- * It will return to the external caller whatever the implementation returns.
- * @param implementation Address to delegate.
- */
- function _delegate(address implementation) internal {
- assembly {
- // Copy msg.data. We take full control of memory in this inline assembly
- // block because it will not return to Solidity code. We overwrite the
- // Solidity scratch pad at memory position 0.
- calldatacopy(0, 0, calldatasize)
-
- // Call the implementation.
- // out and outsize are 0 because we don't know the size yet.
- let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
-
- // Copy the returned data.
- returndatacopy(0, 0, returndatasize)
-
- switch result
- // delegatecall returns 0 on error.
- case 0 { revert(0, returndatasize) }
- default { return(0, returndatasize) }
- }
- }
-
- /**
- * @dev Function that is run as the first thing in the fallback function.
- * Can be redefined in derived contracts to add functionality.
- * Redefinitions must call super._willFallback().
- */
- function _willFallback() internal {
- }
-
- /**
- * @dev fallback implementation.
- * Extracted to enable manual triggering.
- */
- function _fallback() internal {
- _willFallback();
- _delegate(_implementation());
- }
-}
-
-// File: openzeppelin-solidity/contracts/AddressUtils.sol
-
-/**
- * Utility library of inline functions on addresses
- */
-library AddressUtils {
-
- /**
- * Returns whether the target address is a contract
- * @dev This function will return false if invoked during the constructor of a contract,
- * as the code is not actually created until after the constructor finishes.
- * @param addr address to check
- * @return whether the target address is a contract
- */
- function isContract(address addr) internal view returns (bool) {
- uint256 size;
- // XXX Currently there is no better way to check if there is a contract in an address
- // than to check the size of the code at that address.
- // See https://ethereum.stackexchange.com/a/14016/36603
- // for more details about how this works.
- // TODO Check this again before the Serenity release, because all addresses will be
- // contracts then.
- // solium-disable-next-line security/no-inline-assembly
- assembly { size := extcodesize(addr) }
- return size > 0;
- }
-
-}
-
-// File: zos-lib/contracts/upgradeability/UpgradeabilityProxy.sol
-
-/**
- * @title UpgradeabilityProxy
- * @dev This contract implements a proxy that allows to change the
- * implementation address to which it will delegate.
- * Such a change is called an implementation upgrade.
- */
-contract UpgradeabilityProxy is Proxy {
- /**
- * @dev Emitted when the implementation is upgraded.
- * @param implementation Address of the new implementation.
- */
- event Upgraded(address implementation);
-
- /**
- * @dev Storage slot with the address of the current implementation.
- * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is
- * validated in the constructor.
- */
- bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;
-
- /**
- * @dev Contract constructor.
- * @param _implementation Address of the initial implementation.
- */
- constructor(address _implementation) public {
- assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation"));
-
- _setImplementation(_implementation);
- }
-
- /**
- * @dev Returns the current implementation.
- * @return Address of the current implementation
- */
- function _implementation() internal view returns (address impl) {
- bytes32 slot = IMPLEMENTATION_SLOT;
- assembly {
- impl := sload(slot)
- }
- }
-
- /**
- * @dev Upgrades the proxy to a new implementation.
- * @param newImplementation Address of the new implementation.
- */
- function _upgradeTo(address newImplementation) internal {
- _setImplementation(newImplementation);
- emit Upgraded(newImplementation);
- }
-
- /**
- * @dev Sets the implementation address of the proxy.
- * @param newImplementation Address of the new implementation.
- */
- function _setImplementation(address newImplementation) private {
- require(AddressUtils.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
-
- bytes32 slot = IMPLEMENTATION_SLOT;
-
- assembly {
- sstore(slot, newImplementation)
- }
- }
-}
-
-// File: zos-lib/contracts/upgradeability/AdminUpgradeabilityProxy.sol
-
-/**
- * @title AdminUpgradeabilityProxy
- * @dev This contract combines an upgradeability proxy with an authorization
- * mechanism for administrative tasks.
- * All external functions in this contract must be guarded by the
- * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity
- * feature proposal that would enable this to be done automatically.
- */
-contract AdminUpgradeabilityProxy is UpgradeabilityProxy {
- /**
- * @dev Emitted when the administration has been transferred.
- * @param previousAdmin Address of the previous admin.
- * @param newAdmin Address of the new admin.
- */
- event AdminChanged(address previousAdmin, address newAdmin);
-
- /**
- * @dev Storage slot with the admin of the contract.
- * This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is
- * validated in the constructor.
- */
- bytes32 private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b;
-
- /**
- * @dev Modifier to check whether the `msg.sender` is the admin.
- * If it is, it will run the function. Otherwise, it will delegate the call
- * to the implementation.
- */
- modifier ifAdmin() {
- if (msg.sender == _admin()) {
- _;
- } else {
- _fallback();
- }
- }
-
- /**
- * Contract constructor.
- * It sets the `msg.sender` as the proxy administrator.
- * @param _implementation address of the initial implementation.
- */
- constructor(address _implementation) UpgradeabilityProxy(_implementation) public {
- assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin"));
-
- _setAdmin(msg.sender);
- }
-
- /**
- * @return The address of the proxy admin.
- */
- function admin() external view ifAdmin returns (address) {
- return _admin();
- }
-
- /**
- * @return The address of the implementation.
- */
- function implementation() external view ifAdmin returns (address) {
- return _implementation();
- }
-
- /**
- * @dev Changes the admin of the proxy.
- * Only the current admin can call this function.
- * @param newAdmin Address to transfer proxy administration to.
- */
- function changeAdmin(address newAdmin) external ifAdmin {
- require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address");
- emit AdminChanged(_admin(), newAdmin);
- _setAdmin(newAdmin);
- }
-
- /**
- * @dev Upgrade the backing implementation of the proxy.
- * Only the admin can call this function.
- * @param newImplementation Address of the new implementation.
- */
- function upgradeTo(address newImplementation) external ifAdmin {
- _upgradeTo(newImplementation);
- }
-
- /**
- * @dev Upgrade the backing implementation of the proxy and call a function
- * on the new implementation.
- * This is useful to initialize the proxied contract.
- * @param newImplementation Address of the new implementation.
- * @param data Data to send as msg.data in the low level call.
- * It should include the signature and the parameters of the function to be
- * called, as described in
- * https://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector-and-argument-encoding.
- */
- function upgradeToAndCall(address newImplementation, bytes data) payable external ifAdmin {
- _upgradeTo(newImplementation);
- require(address(this).call.value(msg.value)(data));
- }
-
- /**
- * @return The admin slot.
- */
- function _admin() internal view returns (address adm) {
- bytes32 slot = ADMIN_SLOT;
- assembly {
- adm := sload(slot)
- }
- }
-
- /**
- * @dev Sets the address of the proxy admin.
- * @param newAdmin Address of the new proxy admin.
- */
- function _setAdmin(address newAdmin) internal {
- bytes32 slot = ADMIN_SLOT;
-
- assembly {
- sstore(slot, newAdmin)
- }
- }
-
- /**
- * @dev Only fall back when the sender is not the admin.
- */
- function _willFallback() internal {
- require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin");
- super._willFallback();
- }
-}
-
-// File: contracts/FiatTokenProxy.sol
-
-/**
-* Copyright CENTRE SECZ 2018
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is furnished to
-* do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-pragma solidity ^0.4.24;
-
-
-/**
- * @title FiatTokenProxy
- * @dev This contract proxies FiatToken calls and enables FiatToken upgrades
-*/
-contract FiatTokenProxy is AdminUpgradeabilityProxy {
- constructor(address _implementation) public AdminUpgradeabilityProxy(_implementation) {
- }
-}
\ No newline at end of file
diff --git a/validate/FiatTokenV1.etherscan b/validate/FiatTokenV1.etherscan
deleted file mode 100644
index d9c496db4..000000000
--- a/validate/FiatTokenV1.etherscan
+++ /dev/null
@@ -1,606 +0,0 @@
-pragma solidity ^0.4.24;
-
-// File: contracts/Ownable.sol
-
-/**
-* Copyright CENTRE SECZ 2018
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is furnished to
-* do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-pragma solidity ^0.4.24;
-
-/**
- * @title Ownable
- * @dev The Ownable contract from https://github.com/zeppelinos/labs/blob/master/upgradeability_ownership/contracts/ownership/Ownable.sol
- * branch: master commit: 3887ab77b8adafba4a26ace002f3a684c1a3388b modified to:
- * 1) Add emit prefix to OwnershipTransferred event (7/13/18)
- * 2) Replace constructor with constructor syntax (7/13/18)
- * 3) consolidate OwnableStorage into this contract
- */
-contract Ownable {
-
- // Owner of the contract
- address private _owner;
-
- /**
- * @dev Event to show ownership has been transferred
- * @param previousOwner representing the address of the previous owner
- * @param newOwner representing the address of the new owner
- */
- event OwnershipTransferred(address previousOwner, address newOwner);
-
- /**
- * @dev The constructor sets the original owner of the contract to the sender account.
- */
- constructor() public {
- setOwner(msg.sender);
- }
-
- /**
- * @dev Tells the address of the owner
- * @return the address of the owner
- */
- function owner() public view returns (address) {
- return _owner;
- }
-
- /**
- * @dev Sets a new owner address
- */
- function setOwner(address newOwner) internal {
- _owner = newOwner;
- }
-
- /**
- * @dev Throws if called by any account other than the owner.
- */
- modifier onlyOwner() {
- require(msg.sender == owner());
- _;
- }
-
- /**
- * @dev Allows the current owner to transfer control of the contract to a newOwner.
- * @param newOwner The address to transfer ownership to.
- */
- function transferOwnership(address newOwner) public onlyOwner {
- require(newOwner != address(0));
- emit OwnershipTransferred(owner(), newOwner);
- setOwner(newOwner);
- }
-}
-
-// File: contracts/Blacklistable.sol
-
-/**
-* Copyright CENTRE SECZ 2018
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is furnished to
-* do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-pragma solidity ^0.4.24;
-
-
-/**
- * @title Blacklistable Token
- * @dev Allows accounts to be blacklisted by a "blacklister" role
-*/
-contract Blacklistable is Ownable {
-
- address public blacklister;
- mapping(address => bool) internal blacklisted;
-
- event Blacklisted(address indexed _account);
- event UnBlacklisted(address indexed _account);
- event BlacklisterChanged(address indexed newBlacklister);
-
- /**
- * @dev Throws if called by any account other than the blacklister
- */
- modifier onlyBlacklister() {
- require(msg.sender == blacklister);
- _;
- }
-
- /**
- * @dev Throws if argument account is blacklisted
- * @param _account The address to check
- */
- modifier notBlacklisted(address _account) {
- require(blacklisted[_account] == false);
- _;
- }
-
- /**
- * @dev Checks if account is blacklisted
- * @param _account The address to check
- */
- function isBlacklisted(address _account) public view returns (bool) {
- return blacklisted[_account];
- }
-
- /**
- * @dev Adds account to blacklist
- * @param _account The address to blacklist
- */
- function blacklist(address _account) public onlyBlacklister {
- blacklisted[_account] = true;
- emit Blacklisted(_account);
- }
-
- /**
- * @dev Removes account from blacklist
- * @param _account The address to remove from the blacklist
- */
- function unBlacklist(address _account) public onlyBlacklister {
- blacklisted[_account] = false;
- emit UnBlacklisted(_account);
- }
-
- function updateBlacklister(address _newBlacklister) public onlyOwner {
- require(_newBlacklister != address(0));
- blacklister = _newBlacklister;
- emit BlacklisterChanged(blacklister);
- }
-}
-
-// File: contracts/Pausable.sol
-
-/**
-* Copyright CENTRE SECZ 2018
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is furnished to
-* do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-pragma solidity ^0.4.24;
-
-
-/**
- * @title Pausable
- * @dev Base contract which allows children to implement an emergency stop mechanism.
- * Based on openzeppelin tag v1.10.0 commit: feb665136c0dae9912e08397c1a21c4af3651ef3
- * Modifications:
- * 1) Added pauser role, switched pause/unpause to be onlyPauser (6/14/2018)
- * 2) Removed whenNotPause/whenPaused from pause/unpause (6/14/2018)
- * 3) Removed whenPaused (6/14/2018)
- * 4) Switches ownable library to use zeppelinos (7/12/18)
- * 5) Remove constructor (7/13/18)
- */
-contract Pausable is Ownable {
- event Pause();
- event Unpause();
- event PauserChanged(address indexed newAddress);
-
-
- address public pauser;
- bool public paused = false;
-
- /**
- * @dev Modifier to make a function callable only when the contract is not paused.
- */
- modifier whenNotPaused() {
- require(!paused);
- _;
- }
-
- /**
- * @dev throws if called by any account other than the pauser
- */
- modifier onlyPauser() {
- require(msg.sender == pauser);
- _;
- }
-
- /**
- * @dev called by the owner to pause, triggers stopped state
- */
- function pause() onlyPauser public {
- paused = true;
- emit Pause();
- }
-
- /**
- * @dev called by the owner to unpause, returns to normal state
- */
- function unpause() onlyPauser public {
- paused = false;
- emit Unpause();
- }
-
- /**
- * @dev update the pauser role
- */
- function updatePauser(address _newPauser) onlyOwner public {
- require(_newPauser != address(0));
- pauser = _newPauser;
- emit PauserChanged(pauser);
- }
-
-}
-
-// File: openzeppelin-solidity/contracts/math/SafeMath.sol
-
-/**
- * @title SafeMath
- * @dev Math operations with safety checks that throw on error
- */
-library SafeMath {
-
- /**
- * @dev Multiplies two numbers, throws on overflow.
- */
- function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
- // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
- // benefit is lost if 'b' is also tested.
- // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
- if (a == 0) {
- return 0;
- }
-
- c = a * b;
- assert(c / a == b);
- return c;
- }
-
- /**
- * @dev Integer division of two numbers, truncating the quotient.
- */
- function div(uint256 a, uint256 b) internal pure returns (uint256) {
- // assert(b > 0); // Solidity automatically throws when dividing by 0
- // uint256 c = a / b;
- // assert(a == b * c + a % b); // There is no case in which this doesn't hold
- return a / b;
- }
-
- /**
- * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
- */
- function sub(uint256 a, uint256 b) internal pure returns (uint256) {
- assert(b <= a);
- return a - b;
- }
-
- /**
- * @dev Adds two numbers, throws on overflow.
- */
- function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
- c = a + b;
- assert(c >= a);
- return c;
- }
-}
-
-// File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol
-
-/**
- * @title ERC20Basic
- * @dev Simpler version of ERC20 interface
- * See https://github.com/ethereum/EIPs/issues/179
- */
-contract ERC20Basic {
- function totalSupply() public view returns (uint256);
- function balanceOf(address who) public view returns (uint256);
- function transfer(address to, uint256 value) public returns (bool);
- event Transfer(address indexed from, address indexed to, uint256 value);
-}
-
-// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
-
-/**
- * @title ERC20 interface
- * @dev see https://github.com/ethereum/EIPs/issues/20
- */
-contract ERC20 is ERC20Basic {
- function allowance(address owner, address spender)
- public view returns (uint256);
-
- function transferFrom(address from, address to, uint256 value)
- public returns (bool);
-
- function approve(address spender, uint256 value) public returns (bool);
- event Approval(
- address indexed owner,
- address indexed spender,
- uint256 value
- );
-}
-
-// File: contracts/FiatTokenV1.sol
-
-/**
-* Copyright CENTRE SECZ 2018
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is furnished to
-* do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-pragma solidity ^0.4.24;
-
-
-
-
-
-
-/**
- * @title FiatToken
- * @dev ERC20 Token backed by fiat reserves
- */
-contract FiatTokenV1 is Ownable, ERC20, Pausable, Blacklistable {
- using SafeMath for uint256;
-
- string public name;
- string public symbol;
- uint8 public decimals;
- string public currency;
- address public masterMinter;
- bool internal initialized;
-
- mapping(address => uint256) internal balances;
- mapping(address => mapping(address => uint256)) internal allowed;
- uint256 internal totalSupply_ = 0;
- mapping(address => bool) internal minters;
- mapping(address => uint256) internal minterAllowed;
-
- event Mint(address indexed minter, address indexed to, uint256 amount);
- event Burn(address indexed burner, uint256 amount);
- event MinterConfigured(address indexed minter, uint256 minterAllowedAmount);
- event MinterRemoved(address indexed oldMinter);
- event MasterMinterChanged(address indexed newMasterMinter);
-
- function initialize(
- string _name,
- string _symbol,
- string _currency,
- uint8 _decimals,
- address _masterMinter,
- address _pauser,
- address _blacklister,
- address _owner
- ) public {
- require(!initialized);
- require(_masterMinter != address(0));
- require(_pauser != address(0));
- require(_blacklister != address(0));
- require(_owner != address(0));
-
- name = _name;
- symbol = _symbol;
- currency = _currency;
- decimals = _decimals;
- masterMinter = _masterMinter;
- pauser = _pauser;
- blacklister = _blacklister;
- setOwner(_owner);
- initialized = true;
- }
-
- /**
- * @dev Throws if called by any account other than a minter
- */
- modifier onlyMinters() {
- require(minters[msg.sender] == true);
- _;
- }
-
- /**
- * @dev Function to mint tokens
- * @param _to The address that will receive the minted tokens.
- * @param _amount The amount of tokens to mint. Must be less than or equal to the minterAllowance of the caller.
- * @return A boolean that indicates if the operation was successful.
- */
- function mint(address _to, uint256 _amount) whenNotPaused onlyMinters notBlacklisted(msg.sender) notBlacklisted(_to) public returns (bool) {
- require(_to != address(0));
- require(_amount > 0);
-
- uint256 mintingAllowedAmount = minterAllowed[msg.sender];
- require(_amount <= mintingAllowedAmount);
-
- totalSupply_ = totalSupply_.add(_amount);
- balances[_to] = balances[_to].add(_amount);
- minterAllowed[msg.sender] = mintingAllowedAmount.sub(_amount);
- emit Mint(msg.sender, _to, _amount);
- emit Transfer(0x0, _to, _amount);
- return true;
- }
-
- /**
- * @dev Throws if called by any account other than the masterMinter
- */
- modifier onlyMasterMinter() {
- require(msg.sender == masterMinter);
- _;
- }
-
- /**
- * @dev Get minter allowance for an account
- * @param minter The address of the minter
- */
- function minterAllowance(address minter) public view returns (uint256) {
- return minterAllowed[minter];
- }
-
- /**
- * @dev Checks if account is a minter
- * @param account The address to check
- */
- function isMinter(address account) public view returns (bool) {
- return minters[account];
- }
-
- /**
- * @dev Get allowed amount for an account
- * @param owner address The account owner
- * @param spender address The account spender
- */
- function allowance(address owner, address spender) public view returns (uint256) {
- return allowed[owner][spender];
- }
-
- /**
- * @dev Get totalSupply of token
- */
- function totalSupply() public view returns (uint256) {
- return totalSupply_;
- }
-
- /**
- * @dev Get token balance of an account
- * @param account address The account
- */
- function balanceOf(address account) public view returns (uint256) {
- return balances[account];
- }
-
- /**
- * @dev Adds blacklisted check to approve
- * @return True if the operation was successful.
- */
- function approve(address _spender, uint256 _value) whenNotPaused notBlacklisted(msg.sender) notBlacklisted(_spender) public returns (bool) {
- allowed[msg.sender][_spender] = _value;
- emit Approval(msg.sender, _spender, _value);
- return true;
- }
-
- /**
- * @dev Transfer tokens from one address to another.
- * @param _from address The address which you want to send tokens from
- * @param _to address The address which you want to transfer to
- * @param _value uint256 the amount of tokens to be transferred
- * @return bool success
- */
- function transferFrom(address _from, address _to, uint256 _value) whenNotPaused notBlacklisted(_to) notBlacklisted(msg.sender) notBlacklisted(_from) public returns (bool) {
- require(_to != address(0));
- require(_value <= balances[_from]);
- require(_value <= allowed[_from][msg.sender]);
-
- balances[_from] = balances[_from].sub(_value);
- balances[_to] = balances[_to].add(_value);
- allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
- emit Transfer(_from, _to, _value);
- return true;
- }
-
- /**
- * @dev transfer token for a specified address
- * @param _to The address to transfer to.
- * @param _value The amount to be transferred.
- * @return bool success
- */
- function transfer(address _to, uint256 _value) whenNotPaused notBlacklisted(msg.sender) notBlacklisted(_to) public returns (bool) {
- require(_to != address(0));
- require(_value <= balances[msg.sender]);
-
- balances[msg.sender] = balances[msg.sender].sub(_value);
- balances[_to] = balances[_to].add(_value);
- emit Transfer(msg.sender, _to, _value);
- return true;
- }
-
- /**
- * @dev Function to add/update a new minter
- * @param minter The address of the minter
- * @param minterAllowedAmount The minting amount allowed for the minter
- * @return True if the operation was successful.
- */
- function configureMinter(address minter, uint256 minterAllowedAmount) whenNotPaused onlyMasterMinter public returns (bool) {
- minters[minter] = true;
- minterAllowed[minter] = minterAllowedAmount;
- emit MinterConfigured(minter, minterAllowedAmount);
- return true;
- }
-
- /**
- * @dev Function to remove a minter
- * @param minter The address of the minter to remove
- * @return True if the operation was successful.
- */
- function removeMinter(address minter) onlyMasterMinter public returns (bool) {
- minters[minter] = false;
- minterAllowed[minter] = 0;
- emit MinterRemoved(minter);
- return true;
- }
-
- /**
- * @dev allows a minter to burn some of its own tokens
- * Validates that caller is a minter and that sender is not blacklisted
- * amount is less than or equal to the minter's account balance
- * @param _amount uint256 the amount of tokens to be burned
- */
- function burn(uint256 _amount) whenNotPaused onlyMinters notBlacklisted(msg.sender) public {
- uint256 balance = balances[msg.sender];
- require(_amount > 0);
- require(balance >= _amount);
-
- totalSupply_ = totalSupply_.sub(_amount);
- balances[msg.sender] = balance.sub(_amount);
- emit Burn(msg.sender, _amount);
- emit Transfer(msg.sender, address(0), _amount);
- }
-
- function updateMasterMinter(address _newMasterMinter) onlyOwner public {
- require(_newMasterMinter != address(0));
- masterMinter = _newMasterMinter;
- emit MasterMinterChanged(masterMinter);
- }
-}
\ No newline at end of file
diff --git a/validate/README.contractDiff.md b/validate/README.contractDiff.md
deleted file mode 100644
index 6b4358f37..000000000
--- a/validate/README.contractDiff.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# Overview
-
-The `checkDiff` script compares source code uploaded to Etherscan to source code
-on the local machine.
-
-The source code in Etherscan is a concatenation of several files. The script
-reads comments inside the files to determine which local files were used, then
-it reads the file and reconstructs the expected source code.
-
-The script displays a `diff` between the actual and expected code. The
-difference should fall in the following categories:
-
-1. Comments / whitespace
-2. The local code has `import` statements not included in Etherscan because the
- files were explicitly concatenated into a master file.
-3. The local code has extra `pragma solidity ^0.4.24` statements at the head of
- each file, while Etherscan should have just one at the top.
-
-At the end of the run, `checkDiff` will output which files it was able to
-process. Success means that the Etherscan file could be read AND all the
-included files could be read. Validity should be determined by actually looking
-at the diffs.
-
-# Running checkDiff.js
-
-To run the script, type
-
-`node validate/contractDiff.js ... `
-
-Where the `filename` is the location of source code downloaded from Etherscan.
-Copies of `FiatTokenProxy` and `FiatTokenV1` are included for testing purposes.
-You can test them:
-
-`node validate/contractDiff.js validate/FiatTokenProxy.etherscan validate/FiatTokenV1.etherscan`
-
-# Finding code on Etherscan
-
-1. Go to [https://etherscan.io](https://etherscan.io)
-2. Enter the contract address in the search bar.
-3. Click on the `Code` tab.
-
-# Uploading to Etherscan
-
-When uploading source code to Etherscan, you will need to combine several file.
-Before the start of an included file, add the comment:
-
-`// File: `
-
-For example, to include `contracts/Ownable.sol`, add the comment
-
-`// File: contracts/Ownable.sol`
-
-For Open Zeppelin files, omit the `node_modules` directory. For example:
-
-`// File: openzeppelin-solidity/contracts/math/SafeMath.sol`
-
-`// File: zos-lib/contracts/upgradeability/Proxy.sol`
diff --git a/validate/README.validate.md b/validate/README.validate.md
deleted file mode 100644
index 2e4348451..000000000
--- a/validate/README.validate.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Overview
-
-The `validate.js` script connects to the Ethereum blockchain to validate the
-values stored in the contract.
-
-# Infura Setup
-
-Note: Infura is a 3rd party provider.
-
-1. Got to [https://infura.io](https://infura.io) and click "Get Started For
- Free" to register an email with Infura.
-
-2. Click on the "Dashboards" icon at the top of the Infura homepage or go to
- https://infura.io/dashboard to access your personal dashboard.
-
-3. Create a new project - give it any name you want. Then whitelist the Token
- Proxy and the current Token Implementation addresses.
-
-4. Follow the instructions under the "Deployment" section in `README.md` to
- configure the mnemonic phrase and the Infura API key in `config.js`.
-
-# Configure Expected Values
-
-Go to ./validate/validate.js and change the addresses at the top of the file, as
-well as any other constants.
-
-# Validation
-
-Run `truffle exec ./validate/validate.js --network mainnet`
-
-You can replace `mainnet` with any other network defined in `truffle.js` under
-`networks`.
diff --git a/validate/contractDiff.js b/validate/contractDiff.js
deleted file mode 100644
index 2eac2cc2e..000000000
--- a/validate/contractDiff.js
+++ /dev/null
@@ -1,119 +0,0 @@
-const fs = require("fs");
-const chalk = require("chalk");
-const diff = require("diff");
-
-function readFileSync(filename) {
- return fs.readFileSync(filename, "utf8");
-}
-
-function getFilenamesFromCode(code) {
- // find all lines with prefix "// File:"
- const filenames = code.match(/\/\/\s*File:\s*\S+\n/gi);
- for (let i = 0; i < filenames.length; i++) {
- // remove prefix "// File: ".
- filenames[i] = filenames[i].replace(/\/\/\s*File:\s*/i, "");
- filenames[i] = filenames[i].replace(/\s+/i, "");
-
- // directory openzeppelin-solidity is inside node_modules
- if (filenames[i].match(/openzeppelin-solidity/)) {
- filenames[i] = "node_modules/" + filenames[i];
- }
-
- // directory zos-lib is inside node_modules
- if (filenames[i].match(/zos-lib/)) {
- filenames[i] = "node_modules/" + filenames[i];
- }
-
- // add ./ prefix
- filenames[i] = "./" + filenames[i];
- console.log(filenames[i]);
- }
- return filenames;
-}
-
-function createCodeFile(filenames) {
- let code = "";
- for (let i = 0; i < filenames.length; i++) {
- try {
- console.log("Reading file " + filenames[i]);
- } catch (err) {
- console.log("Could not read file " + filenames[i]);
- return "";
- }
- code = code + readFileSync(filenames[i]) + "\n";
- }
- return code;
-}
-
-function diffText(code1, code2) {
- const diffOutput = diff.diffTrimmedLines(code1, code2);
- for (let i = 0; i < diffOutput.length; i++) {
- const diffLine = diffOutput[i];
- if (diffLine.added) {
- process.stdout.write(chalk.green(`+ ${diffLine.value}`));
- } else if (diffLine.removed) {
- process.stdout.write(chalk.red(`- ${diffLine.value}`));
- }
- }
-}
-
-function removeExtraComments(code) {
- const modified = code.replace(/\/\/\s*File:\s*\S+\n/gi, "");
- return modified;
-}
-
-function validate(filename) {
- let code = readFileSync(filename);
-
- const filenames = getFilenamesFromCode(code);
- const expectedCode = createCodeFile(filenames);
-
- code = removeExtraComments(code);
- diffText(code, expectedCode);
-}
-
-function printUsage() {
- console.log("node contractDiff .... ");
-}
-
-function main() {
- if (process.argv.length < 3) {
- printUsage();
- return;
- }
-
- let fail = 0;
- const total = process.argv.length - 2;
- let goodFiles = "";
- let badFiles = "";
-
- for (let i = 2; i < process.argv.length; i++) {
- const filename = process.argv[i];
- console.log("Checking: " + filename);
- try {
- validate(filename);
- goodFiles = goodFiles + filename + "\n";
- } catch (err) {
- console.log("Error validating file " + filename);
- console.log(err.msg);
- badFiles = badFiles + filename + "\n";
- ++fail;
- }
- }
-
- if (total - fail > 0) {
- process.stdout.write(
- chalk.green("\n\nSuccessfully processed " + (total - fail) + " files.\n")
- );
- process.stdout.write(chalk.green(goodFiles));
- }
-
- if (fail > 0) {
- process.stdout.write(
- chalk.red("\n\nFailed to process " + fail + " files.\n")
- );
- process.stdout.write(chalk.red(badFiles + "\n"));
- }
-}
-
-main();
diff --git a/validate/validate.js b/validate/validate.js
deleted file mode 100644
index f00848e91..000000000
--- a/validate/validate.js
+++ /dev/null
@@ -1,153 +0,0 @@
-// Address of the FiatToken Implementation
-const fiatTokenAddress = "0x0882477e7895bdc5cea7cb1552ed914ab157fe56";
-
-// Address of the FiatToken Proxy
-const fiatTokenProxyAddress = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
-
-// role addresses
-const MASTER_MINTER = 0x1500a138523709ce66c8b9abe678abc1b6c5a7b7;
-const PAUSER = 0xe8e13e1b6d363c270ef3a5ab466ebad8326311bb;
-const UPGRADER = 0x69005ff70072c57547dc44ea975d85ea60e5b196;
-const OWNER = 0xa61e278899a8553d93d14eb19ba2791e05069e87;
-const BLACKLISTER = 0x063d13783a0a2ce65b1ca00d9e897e6c8b1ec86b;
-
-// Addresses of known minters - currently fake minters
-// If replacing with real minters need to modify printMinterInfo
-const minters = ["0x0000", "0x0001"];
-
-const NAME = "USD//C";
-const SYMBOL = "USDC";
-const CURRENCY = "USD";
-const DECIMALS = 6;
-const TOTALSUPPLY = 0;
-const PAUSED = false;
-
-// Name of current implementation artifact as stored in ./build/contracts/*.json
-const FiatTokenV1 = artifacts.require("FiatTokenV1");
-
-// Name of current proxy artifact as stored in ./build/contracts/*.json
-artifacts.require("FiatTokenProxy");
-
-//
-//
-// Validation code
-//
-//
-
-const adminSlot =
- "0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b";
-const implSlot =
- "0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3";
-
-const asyncGetStorageAt = (address, slot) =>
- new Promise((resolve, reject) => {
- web3.eth.getStorageAt(address, slot, (err, result) => {
- if (err) {
- return reject(err);
- }
- resolve(result);
- });
- });
-
-async function printMinterInfo(proxiedToken) {
- for (const minter of minters) {
- console.log("\nMinter: " + minter);
-
- const isMinter = await proxiedToken.isMinter.call(minter);
- print("isMinter", isMinter, false);
-
- const minterAllowance = await proxiedToken.minterAllowance.call(minter);
- print("mintAllowance", minterAllowance, 0);
-
- const balanceOf = await proxiedToken.balanceOf.call(minter);
- print("balanceOf", balanceOf, 0);
-
- const isBlacklisted = await proxiedToken.isBlacklisted.call(minter);
- print("isBlacklisted", isBlacklisted, false);
- }
-}
-
-function getAddressFromSlotData(slotData) {
- const rawAddress = slotData.substring(26, 86);
- return "0x" + rawAddress;
-}
-
-function compare(actual, expected) {
- if (actual === expected) {
- return "(ok)";
- } else {
- return "(expect " + expected + ")";
- }
-}
-
-function print(name, actual, expected) {
- console.log(name + "\t" + actual + "\t" + compare(actual, expected));
-}
-
-async function Validate() {
- console.log("Connecting to contract...");
- await FiatTokenV1.at(fiatTokenAddress);
- console.log("Token found.");
- const proxiedToken = await FiatTokenV1.at(fiatTokenProxyAddress);
- console.log("Proxied token created.");
-
- // initialized needs to retrieved manually
- let slot8Data = await asyncGetStorageAt(proxiedToken.address, 8);
- let initialized = slot8Data.substring(24, 26);
- print("init proxy", initialized, "01");
-
- slot8Data = await asyncGetStorageAt(fiatTokenAddress, 8);
- initialized = slot8Data.substring(24, 26);
- print("init logic", initialized, "01");
-
- const name = await proxiedToken.name.call();
- print("name ", name, NAME);
-
- const symbol = await proxiedToken.symbol.call();
- print("symbol ", symbol, SYMBOL);
-
- const decimals = await proxiedToken.decimals.call();
- print("decimals", decimals, DECIMALS);
-
- const currency = await proxiedToken.currency.call();
- print("currency", currency, CURRENCY);
-
- const totalSupply = await proxiedToken.totalSupply.call();
- print("totalSupply", totalSupply, TOTALSUPPLY);
-
- const paused = await proxiedToken.paused.call();
- print("paused ", paused, PAUSED);
-
- // implementation
- const implementation = await asyncGetStorageAt(
- proxiedToken.address,
- implSlot
- );
- print("implement", getAddressFromSlotData(implementation), fiatTokenAddress);
-
- const admin = await asyncGetStorageAt(proxiedToken.address, adminSlot);
- print("upgrader", getAddressFromSlotData(admin), UPGRADER);
-
- const owner = await proxiedToken.owner.call();
- print("owner ", owner, OWNER);
-
- const masterMinter = await proxiedToken.masterMinter.call();
- print("masterMinter", masterMinter, MASTER_MINTER);
-
- const pauser = await proxiedToken.pauser.call();
- print("pauser ", pauser, PAUSER);
-
- const blacklister = await proxiedToken.blacklister.call();
- print("blacklister", blacklister, BLACKLISTER);
-
- await printMinterInfo(proxiedToken);
-}
-
-module.exports = async (callback) => {
- try {
- await Validate();
- } catch (e) {
- // continue
- }
- callback();
-};
diff --git a/verification/GoogleSheets/index.js b/verification/GoogleSheets/index.js
deleted file mode 100644
index c92a0411c..000000000
--- a/verification/GoogleSheets/index.js
+++ /dev/null
@@ -1,257 +0,0 @@
-const fs = require("fs");
-const readline = require("readline");
-const { google } = require("googleapis");
-const path = require("path");
-
-const SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"];
-const CREDENTIALS_PATH = path.join(__dirname, "credentials.json");
-const TOKEN_PATH = path.join(__dirname, "/token.json");
-
-/**
- * Authorize access to GoogleSheets API and load spreadsheet data.
- */
-function load() {
- return new Promise((resolve, reject) => {
- // Load client secrets from a local file.
- fs.readFile(CREDENTIALS_PATH, async (err, content) => {
- if (err) {
- reject(new Error("Error loading credentials file:" + err));
- }
- // If no error loading client secrets, authorize and run getTests().
- const res = await authorize(JSON.parse(content), getTests).catch(
- (err) => {
- reject(err);
- }
- );
- resolve(res);
- });
- });
-}
-
-/**
- * Create an OAuth2 client with the given credentials, and then execute the
- * given callback function.
- * @param {Object} credentials The authorization client credentials.
- * @param {function} callback The callback to call with the authorized client.
- */
-function authorize(credentials, callback) {
- // eslint-disable-next-line camelcase
- const { client_secret, client_id, redirect_uris } = credentials.installed;
- const oAuth2Client = new google.auth.OAuth2(
- client_id,
- client_secret,
- redirect_uris[0]
- );
-
- return new Promise((resolve, reject) => {
- // Check if we have previously stored an OAuth token.
- fs.readFile(TOKEN_PATH, async (err, token) => {
- // If we have not previously stored an OAuth token, get a new one and
- // call getTests().
- let res;
- if (err) {
- res = await getNewToken(oAuth2Client, callback).catch((err) => {
- reject(err);
- });
- } else {
- // If we have previously stored an OAuth token, call getTests().
- oAuth2Client.setCredentials(JSON.parse(token));
- res = await callback(oAuth2Client).catch((err) => {
- reject(err);
- });
- }
- resolve(res);
- });
- });
-}
-
-/**
- * Get and store new token after prompting for user authorization, and then
- * execute the given callback with the authorized OAuth2 client.
- * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
- * @param {getEventsCallback} callback The callback for the authorized client.
- */
-function getNewToken(oAuth2Client, callback) {
- const authUrl = oAuth2Client.generateAuthUrl({
- access_type: "offline",
- scope: SCOPES,
- });
- console.log("Authorize this app by visiting this url:", authUrl);
- const rl = readline.createInterface({
- input: process.stdin,
- output: process.stdout,
- });
-
- return new Promise((resolve, reject) => {
- rl.question("Enter the code from that page here: ", (code) => {
- rl.close();
- oAuth2Client.getToken(code, async (err, token) => {
- if (err) {
- reject(await callback(err));
- }
- oAuth2Client.setCredentials(token);
- // Store the token to disk for later program executions
- fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
- if (err) {
- console.error(err);
- }
- console.log("Token stored to", TOKEN_PATH);
- });
- const res = await callback(oAuth2Client).catch((err) => {
- reject(err);
- });
- resolve(res);
- });
- });
- });
-}
-
-/**
- * Gets the tests to verify from the GoogleSheets spreadsheet.
- * @see https://docs.google.com/spreadsheets/d/1zP1_q8XbLH8YrWMJ0Od80PKleklUnvBAX96wypJaVTU/edit?usp=sharing
- * @param {google.auth.OAuth2} auth The authenticated Google OAuth client.
- */
-function getTests(auth) {
- const sheets = google.sheets({ version: "v4", auth });
-
- return new Promise((resolve, reject) => {
- sheets.spreadsheets.get(
- {
- spreadsheetId: "1zP1_q8XbLH8YrWMJ0Od80PKleklUnvBAX96wypJaVTU",
- includeGridData: true,
- },
- (err, res) => {
- if (err) {
- reject(new Error("The GoogleSheets API returned an error: " + err));
- }
- const tests = {};
- const tabs = res.data.sheets;
- if (tabs.length) {
- tabs.map((tab) => {
- const tabName = tab.properties.title;
- if (tabName === "UnitTestCompleteness") {
- loadUnitTestCompleteness(tests, tab);
- return;
- }
- const rows = tab.data[0].rowData;
- const topRow = rows.shift().values;
- const col = getCol(topRow);
- if (typeof col === "undefined") {
- console.log(
- '\nNo code column found in tab "' + tabName + '". Skipping.\n'
- );
- return;
- }
- rows.map((rowData) => {
- const row = rowData.values;
- if (row) {
- processRow(row, tabName, tests, col);
- }
- });
- });
- } else {
- reject(new Error("No GoogleSheets data found."));
- }
- resolve(tests);
- }
- );
- });
-}
-
-/**
- * Helper function that gets the test code and test description from a row in a
- * given speadsheet tab and adds them to the tests object returned by getTests().
- * @param {Array} row The row of the spreadsheet to processs.
- * @param {String} tabName The name of the spreadsheet tab currently loading.
- * @param {Object} tests Contains all the spreadsheet test data to verify.
- * @param {Int} col The index of the test code column of the spreadsheet tab.
- */
-function processRow(row, tabName, tests, col) {
- const codeCell = row[col];
- const descCell = row[col + 1];
- if (codeCell && descCell) {
- let testCode = codeCell.formattedValue;
- const testDesc = descCell.formattedValue;
- if (testCode && testDesc) {
- const pending = testCode.match(/ -p/);
- if (pending) {
- testCode = testCode.replace(pending[0], "");
- }
- categorizeTest(
- tests,
- testCode.trim(),
- testDesc.trim(),
- tabName.trim(),
- pending
- );
- }
- }
-}
-
-/**
- * Helper function that gets all test codes included in tab UnitTestCompleteness.
- * @param {Object} tab The UnitTestCompleteness tab object.
- * @param {Object} tests Contains all the spreadsheet test data to verify.
- */
-function loadUnitTestCompleteness(tests, tab) {
- tests.completeness = {};
- const rows = tab.data[0].rowData;
- rows.map((row) => {
- row = row.values;
- row.map((cell) => {
- cell = cell.formattedValue;
- if (cell) {
- const codes = cell.match(/([a-z]{2,})([0-9]+)/g);
- if (codes != null) {
- codes.map((code) => {
- if (!tests.completeness[code]) {
- tests.completeness[code] = true;
- }
- });
- }
- }
- });
- });
-}
-
-/**
- * Helper function that adds a test code and description to the tests object
- * returned by getTests().
- * @param {Object} tests Contains all the spreadsheet test data to verify.
- * @param {String} code The test code to add to tests.
- * @param {String} desc The test description to add to tests.
- * @param {String} tab The name of the spreadsheet tab currently loading.
- * @param {Array?} pending [' -p'] if test is pending, 'undefined' otherwise.
- */
-function categorizeTest(tests, code, desc, tab, pending) {
- if (pending) {
- tab = "pending";
- }
- if (!tests[tab]) {
- tests[tab] = {};
- }
- const tabTests = tests[tab];
- tabTests[code] = desc.replace(code, "");
- tests[tab] = tabTests;
-}
-
-/**
- * Helper function that finds the 'Code' or 'code' column in a spreadsheet tab.
- * @param {Array} topRow An array containing all the cells along the top row of
- * the spreadsheet tab. Should contain column headers.
- */
-function getCol(topRow) {
- let col;
- for (let i = 0; i < topRow.length; i++) {
- const cell = topRow[i];
- const label = cell.formattedValue;
- if (label === "code" || label === "Code") {
- col = i;
- }
- }
- return col;
-}
-
-module.exports = {
- load,
-};
diff --git a/verification/README.verification.txt b/verification/README.verification.txt
deleted file mode 100644
index 718909f8c..000000000
--- a/verification/README.verification.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-The spreadsheet verification tool requires certain naming and usage conventions
-to function correctly.
-
-Test Codes:
-
-- Should follow the format of lowercase letters followed by a number with
- no spaces. (ex. pt001, ept016, misc0000, legacy2, fiat19)
-
-- Should be included at the beginning of each test title (in the test suite)
- and each test description (in the spreadsheet).
-
-- Should be listed under the 'Code' column of each spreadsheet tab.
-
-Test Titles:
-
-- Should exactly match the test description assigned to the test in the
- spreadsheet.
-
-Spreadsheet Tabs:
-
-- Should have the same name as the test file they represent.
- This name should be formatted BlankTests where Blank consists of uppercase
- and/or lowercase letters and is followed without a space by the word 'Tests'.
- (ex. PositiveTests, tokenTests, ABITests)
-
-- Should include a column 'code' or 'Code' listing all unique test codes that
- correspond to tests expected in the test file.
-
-- Should include a column listing all unique test descriptions that correspond
- to tests expected in the test file. This column should be immediately to the
- right of the test code column and should be ordered such that the test code
- on any given row refers to the same test as the test description on that row.
-
-- Should keep the column headers in the top row.
-
-UnitTestCompleteness tab:
-
-- The verification tool will print out any test codes that are featured in
- the UnitTestCompleteness tab but missing from the test suite.
-- It does not matter where these codes are located in the tab so long as they
- adhere to the same code format used throughout the test suite.
- (i.e. xyz123, where xyz is a sequence of 2+ lowercase letters and 123 is any
- sequence of numbers)
-
-Contract Block Titles:
-
-- Should include the name of the test file they run, and this name should not
- be immediately preceded by letters.
- (ex. If the contract block runs the PositiveTests file, it should be named
- 'FiatToken_PositiveTests', 'PositiveTestsupgraded', 'PositiveTests' etc.,
- but not 'upgradedPositiveTests'.)
-
-- Should include the word 'Legacy' if they run tests that do not need to be
- recorded in the spreadsheet and can be ignored by the verification tool.
-
-Pending Tests:
-
-- Should be flagged with ' -p' immediately after the test code in the
- spreadsheet. This flag should not be included anywhere in the test suite code
- or in the spreadsheet test description.
-- The purpose of the pending flag is to mark tests that you are working on
- but have not yet merged. When other developers use the tool, it will ignore
- the tests that are marked pending rather than alert them that tests are
- missing from their test suite. When you, the developer writing the pending
- tests, use the tool it will simply list the tests you are working on.
- If the tool alerts you that there are tests marked as pending that are also
- included in your version of the test suite, but they are not tests you are
- working on, then the developer who wrote the tests forgot to delete the
- pending flags from the spreadsheet when the tests were merged, and you should
- go ahead and delete them yourself.
-
-
-***Disabling/Enabling Verification***
-
-- To DISABLE the spreadsheet verification tool, go to the file truffle.js and
- comment out the following line:
- reporter: './verification/verification_reporter.js',
- Then, uncomment the line above it.
- //reporter: 'Spec',
-
-- To ENABLE the spreadsheet verification tool FOR THE FIRST TIME.
-
- 1) Ensure your browser is signed in to your Google account and visit
- https://developers.google.com/sheets/api/quickstart/nodejs .
-
- 2) Press the blue 'ENABLE THE GOOGLE SHEETS API' button.
-
- 3) Enter a project name (i.e. 'spreadsheet-verification') and product name
- (i.e 'centre-tokens') and download the credentials.json file.
-
- 4) Move your credentials.json file into the verification/GoogleSheets folder.
-
- 5) Run 'npm run truffle-test'. You should be prompted to visit a URL and enter a code
- that you find there into your terminal. This will create a token.json file
- inside the GoogleSheets folder. Note, if a token.json file already exists in
- this folder, you will encounter an error.
-
- From there, you should be good to go. This process only needs to be completed
- the first time you use the tool.
-
- Note: Ensure that credentials.json and token.json are included in .gitignore
- before committing.
diff --git a/verification/verification_reporter.js b/verification/verification_reporter.js
deleted file mode 100644
index 489fc430e..000000000
--- a/verification/verification_reporter.js
+++ /dev/null
@@ -1,306 +0,0 @@
-const mocha = require("mocha");
-const specReporter = mocha.reporters.Spec;
-const baseReporter = mocha.reporters.Base;
-const { color } = baseReporter;
-const { inherits } = mocha.utils;
-const sheets = require("./GoogleSheets/index");
-const _ = require("lodash");
-const jsdiff = require("diff");
-
-// Global variables for text output.
-const greenX = color("bright pass", baseReporter.symbols.err);
-const redX = color("bright fail", baseReporter.symbols.err);
-const greenOk = color("bright pass", baseReporter.symbols.ok);
-// const redOk = color("bright fail", baseReporter.symbols.ok);
-const indent = " ";
-
-module.exports = verificationReporter;
-
-// Extends default Mocha reporter, 'Spec'.
-inherits(verificationReporter, specReporter);
-
-function verificationReporter(runner) {
- specReporter.call(this, runner);
-
- let spreadsheet;
- let spreadsheetClone;
- const errs = [];
- const pending = {};
-
- // Runs before tests are executed. Loads tests from spreadsheet.
- before("load_spreadsheetTests", async () => {
- this.timeout(200000);
- console.log("Loading spreadsheet...\n");
- spreadsheet = await sheets.load().catch((err) => {
- console.log(err);
- });
- spreadsheetClone = JSON.parse(JSON.stringify(spreadsheet));
- });
-
- // Runs at the beginning of each contract block execution.
- runner.on("suite", (suite) => {
- // If contract block title is marked 'Legacy',
- // we skip verification. (See README.verification)
- const legacy = suite.title.match(/Legacy/gi);
- if (legacy) {
- console.log(
- indent + 'This test file is marked "Legacy". Skipping verification.'
- );
- }
-
- // We also skip verification on the 'PausableTests' file.
- // Remove this block and the one indicated below to re-enable.
- const pausableTests = suite.title.match(/PausableTests/gi);
- if (pausableTests) {
- console.log(
- indent + "Verification tool configured to skip PausableTests file."
- );
- }
- });
-
- // Runs at the end of every test.
- runner.on("test end", (test) => {
- // If contract block title is marked 'Legacy',
- // we skip verification. (See README.verification)
- const legacy = test.parent.title.match(/Legacy/gi);
- if (legacy) {
- return;
- }
-
- // We also skip verification on the 'PausableTests' file.
- // Remove this block and the one indicated above to re-enable.
- const pausableTests = test.parent.title.match(/PausableTests/gi);
- if (pausableTests) {
- return;
- }
-
- // Parse test title.
- let file = test.parent.title.match(/[a-z]+Tests/gi);
- if (file) {
- file = file[0];
- } else {
- console.log(
- indent +
- color(
- "pass",
- "Error parsing test title.\n" +
- indent +
- "Confirm file name is formatted correctly and included in contract \n" +
- indent +
- "block title. (See README.verification)"
- )
- );
- return;
- }
- let id = test.title.match(/([a-z]{2,})([0-9]+)/g);
- if (id) {
- id = id[0];
- } else {
- console.log(
- indent +
- color(
- "pass",
- "Error parsing test title.\n" +
- indent +
- "Confirm id is formatted correctly and included in test title.\n" +
- indent +
- "(See README.verification)"
- )
- );
- return;
- }
- const testRan = test.title.replace(id, "");
-
- // Check if test is in UnitTestCompleteness tab and "cross-off" if it is.
- if (!_.isEmpty(spreadsheet.completeness)) {
- if (spreadsheet.completeness[id]) {
- delete spreadsheet.completeness[id];
- }
- }
-
- // If test is marked pending in spreadsheet, record for later output.
- if (spreadsheet.pending && spreadsheet.pending[id] === testRan) {
- console.log(indent + greenX + color("bright pass", " pending"));
- pending[id] = testRan;
- } else {
- // Verify test is in spreadsheet.
- if (spreadsheet[file]) {
- const spreadsheetTest =
- spreadsheet[file][id] || spreadsheetClone[file][id];
- if (spreadsheetTest) {
- // Verify test descriptions match.
- if (spreadsheetTest === testRan) {
- console.log(indent + greenX);
- } else {
- // If test is in spreadsheet, but descriptions don't match.
- console.log(
- indent +
- redX +
- color(
- "fail",
- " test description inconsistent with spreadsheet for " +
- id +
- ", " +
- file
- )
- );
- // Print test description string diff.
- const diff = getStringDiff(testRan, spreadsheetTest);
- console.log(indent + diff);
- errs.push(
- redX +
- color(
- "fail",
- " Test descriptions do not match for " + id + ", " + file
- ) +
- "\n" +
- indent +
- "In spreadsheet: " +
- spreadsheetTest +
- "\n" +
- indent +
- "In test file: " +
- testRan +
- "\n" +
- indent +
- "Diff: " +
- diff
- );
- }
- // If test is included in spreadsheet, 'cross-off' by deleting.
- if (spreadsheet[file][id]) {
- delete spreadsheet[file][id];
- }
- } else {
- // If test is not in spreadsheet.
- console.log(
- indent +
- redX +
- color("fail", " " + id + " missing from spreadsheet tab " + file)
- );
- errs.push(
- redX +
- color(
- "fail",
- " Test " + id + " missing from " + file + " spreadsheet tab."
- )
- );
- }
- } else {
- // If test file not found in spreadsheet tabs.
- console.log(
- indent +
- redX +
- color(
- "fail",
- " test file " + file + " does not match a spreadsheet tab"
- )
- );
- errs.push(
- redX +
- color(
- "fail",
- " Test file " +
- file +
- " missing from spreadsheet. Possible solutions:\n" +
- "1. Ensure test is listed in correct spreadsheet tab.\n" +
- "2. Ensure the tab name is included in the contract block title.\n" +
- "(See README.verification)"
- )
- );
- }
- }
- });
-
- // Runs at the end of test suite execution. Prints verification summary.
- runner.on("end", () => {
- console.log("\n\nSpreadsheet Verification Summary:\n");
- // If there are pending tests included in the test suite...
- if (!_.isEmpty(pending)) {
- console.log(color("bright pass", "Pending Tests:"));
- console.log(
- "The following tests are included in the test suite, but\n" +
- "marked pending in the spreadsheet (delete -p flag once merged): "
- );
- console.log(pending);
- }
- // Do not report tests that are missing from test suite but marked pending.
- delete spreadsheet.pending;
- // Print out any tests that are included in UnitTestCompleteness tab but
- // missing from the test suite.
- if (!_.isEmpty(spreadsheet.completeness)) {
- console.log(
- "\n" +
- redX +
- color(
- "bright fail",
- " UnitTestCompleteness tab includes tests that are not present in test suite:"
- ) +
- "\n" +
- Object.keys(spreadsheet.completeness).toString()
- );
- } else {
- console.log(
- greenOk +
- color(
- "bright pass",
- " Test suite suite contains all tests in UnitTestCompleteness tab."
- )
- );
- }
- delete spreadsheet.completeness;
- // If all the tests in a tab are present, 'cross-off' tab by deleting.
- for (const file in spreadsheet) {
- if (_.isEmpty(spreadsheet[file])) {
- delete spreadsheet[file];
- }
- }
- // If all tests are 'crossed-off', print success.
- if (_.isEmpty(spreadsheet)) {
- console.log(
- "\n" +
- greenOk +
- color("bright pass", " Test suite contains all tests in spreadsheet.")
- );
- } else {
- // If not all tests are 'crossed-off', print the tests remaining.
- console.log(
- color(
- "bright fail",
- "\nTests missing from test suite (but included in spreadsheet):\n"
- )
- );
- console.log(spreadsheet);
- }
- // Print all errors where executed tests did not match spreadsheet.
- if (errs.length) {
- console.log(
- color(
- "bright fail",
- "\nTests missing from spreadsheet (but included in test suite): "
- )
- );
- errs.map((err) => {
- console.log("\n" + err);
- });
- } else {
- console.log(
- "\n" +
- greenOk +
- color("bright pass", " Spreadsheet contains all tests in test suite.")
- );
- }
- });
-}
-
-// Helper function that takes in two strings and returns a color coded diff.
-function getStringDiff(string1, string2) {
- let diff = "";
- const diffList = jsdiff.diffChars(string1, string2);
- diffList.map((part) => {
- // green for additions, red for deletions, grey for common parts
- const col = part.added ? "green" : part.removed ? "red" : "grey";
- diff += part.value[col];
- });
- return diff;
-}
diff --git a/verification_artifacts/input.template.json b/verification_artifacts/input.template.json
new file mode 100644
index 000000000..bc61264bd
--- /dev/null
+++ b/verification_artifacts/input.template.json
@@ -0,0 +1,15 @@
+{
+ "SignatureChecker": {
+ "contractAddress": "",
+ "contractCreationTxHash": ""
+ },
+ "FiatTokenV2_2": {
+ "contractAddress": "",
+ "contractCreationTxHash": ""
+ },
+ "FiatTokenProxy": {
+ "contractAddress": "",
+ "contractCreationTxHash": ""
+ },
+ "rpcUrl": ""
+}
diff --git a/yarn.lock b/yarn.lock
index 95a8b2c8a..374c6a739 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,419 +2,1455 @@
# yarn lockfile v1
-"@babel/code-frame@^7.0.0":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
- integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
+"@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==
+
+"@adraffy/ens-normalize@1.10.1":
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069"
+ integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==
+
+"@assemblyscript/loader@^0.9.4":
+ version "0.9.4"
+ resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.9.4.tgz#a483c54c1253656bb33babd464e3154a173e1577"
+ integrity sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA==
+
+"@babel/code-frame@7.12.11":
+ version "7.12.11"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
+ integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
dependencies:
"@babel/highlight" "^7.10.4"
-"@babel/helper-module-imports@^7.10.4":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620"
- integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==
+"@babel/code-frame@^7.0.0":
+ version "7.22.5"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658"
+ integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==
dependencies:
- "@babel/types" "^7.10.4"
+ "@babel/highlight" "^7.22.5"
-"@babel/helper-plugin-utils@^7.10.4":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375"
- integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==
+"@babel/helper-validator-identifier@^7.22.5":
+ version "7.22.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193"
+ integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==
-"@babel/helper-validator-identifier@^7.10.4":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
- integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
-
-"@babel/highlight@^7.10.4":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
- integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
+"@babel/highlight@^7.10.4", "@babel/highlight@^7.22.5":
+ version "7.22.5"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031"
+ integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==
dependencies:
- "@babel/helper-validator-identifier" "^7.10.4"
+ "@babel/helper-validator-identifier" "^7.22.5"
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/plugin-transform-runtime@^7.5.5":
- version "7.10.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.5.tgz#3b39b7b24830e0c2d8ff7a4489fe5cf99fbace86"
- integrity sha512-tV4V/FjElJ9lQtyjr5xD2IFFbgY46r7EeVu5a8CpEKT5laheHKSlFeHjpkPppW3PqzGLAuv5k2qZX5LgVZIX5w==
+"@babel/runtime@^7.4.4":
+ version "7.22.10"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682"
+ integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==
dependencies:
- "@babel/helper-module-imports" "^7.10.4"
- "@babel/helper-plugin-utils" "^7.10.4"
- resolve "^1.8.1"
- semver "^5.5.1"
+ regenerator-runtime "^0.14.0"
+
+"@chainsafe/as-sha256@^0.3.1":
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9"
+ integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==
-"@babel/runtime@^7.5.5":
- version "7.10.5"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.5.tgz#303d8bd440ecd5a491eae6117fd3367698674c5c"
- integrity sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==
+"@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:
- regenerator-runtime "^0.13.4"
+ "@chainsafe/as-sha256" "^0.3.1"
-"@babel/types@^7.10.4":
- version "7.10.5"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.5.tgz#d88ae7e2fde86bfbfe851d4d81afa70a997b5d15"
- integrity sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==
+"@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:
- "@babel/helper-validator-identifier" "^7.10.4"
- lodash "^4.17.19"
- to-fast-properties "^2.0.0"
-
-"@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"
- integrity sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==
- dependencies:
- "@ethersproject/address" ">=5.0.0-beta.128"
- "@ethersproject/bignumber" ">=5.0.0-beta.130"
- "@ethersproject/bytes" ">=5.0.0-beta.129"
- "@ethersproject/constants" ">=5.0.0-beta.128"
- "@ethersproject/hash" ">=5.0.0-beta.128"
- "@ethersproject/keccak256" ">=5.0.0-beta.127"
- "@ethersproject/logger" ">=5.0.0-beta.129"
- "@ethersproject/properties" ">=5.0.0-beta.131"
- "@ethersproject/strings" ">=5.0.0-beta.130"
-
-"@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.0":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.2.tgz#80d0ddfb7d4bd0d32657747fa4bdd2defef2e00a"
- integrity sha512-+rz26RKj7ujGfQynys4V9VJRbR+wpC6eL8F22q3raWMH3152Ha31GwJPWzxE/bEA+43M/zTNVwY0R53gn53L2Q==
+ "@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:
- "@ethersproject/bignumber" "^5.0.0"
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/keccak256" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
- "@ethersproject/rlp" "^5.0.0"
- bn.js "^4.4.0"
+ "@chainsafe/as-sha256" "^0.3.1"
+ "@chainsafe/persistent-merkle-tree" "^0.5.0"
-"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.0":
- version "5.0.5"
- resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.5.tgz#31bd7e75aad46ace345fae69b1f5bb120906af1b"
- integrity sha512-24ln7PV0g8ZzjcVZiLW9Wod0i+XCmK6zKkAaxw5enraTIT1p7gVOcSXFSzNQ9WYAwtiFQPvvA+TIO2oEITZNJA==
+"@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:
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
- bn.js "^4.4.0"
+ "@chainsafe/as-sha256" "^0.3.1"
+ "@chainsafe/persistent-merkle-tree" "^0.4.2"
+ case "^1.6.3"
-"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0":
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.3.tgz#b3769963ae0188a35713d343890a903bda20af9c"
- integrity sha512-AyPMAlY+Amaw4Zfp8OAivm1xYPI8mqiUYmEnSUk1CnS2NrQGHEMmFJFiOJdS3gDDpgSOFhWIjZwxKq2VZpqNTA==
+"@colors/colors@1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
+ integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
+
+"@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:
- "@ethersproject/logger" "^5.0.0"
+ "@jridgewell/trace-mapping" "0.3.9"
-"@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.0":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.2.tgz#f7ac0b320e2bbec1a5950da075015f8bc4e8fed1"
- integrity sha512-nNoVlNP6bgpog7pQ2EyD1xjlaXcy1Cl4kK5v1KoskHj58EtB6TK8M8AFGi3GgHTdMldfT4eN3OsoQ/CdOTVNFA==
+"@ensdomains/address-encoder@^0.1.7":
+ version "0.1.9"
+ resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d"
+ integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==
dependencies:
- "@ethersproject/bignumber" "^5.0.0"
+ bech32 "^1.1.3"
+ blakejs "^1.1.0"
+ bn.js "^4.11.8"
+ bs58 "^4.0.1"
+ crypto-addr-codec "^0.1.7"
+ nano-base32 "^1.0.1"
+ ripemd160 "^2.0.2"
-"@ethersproject/hash@>=5.0.0-beta.128":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.2.tgz#6d69558786961836d530b8b4a8714eac5388aec7"
- integrity sha512-dWGvNwmVRX2bxoQQ3ciMw46Vzl1nqfL+5R8+2ZxsRXD3Cjgw1dL2mdjJF7xMMWPvPdrlhKXWSK0gb8VLwHZ8Cw==
+"@ensdomains/ens@0.4.5":
+ version "0.4.5"
+ resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc"
+ integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==
dependencies:
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/keccak256" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
- "@ethersproject/strings" "^5.0.0"
+ bluebird "^3.5.2"
+ eth-ens-namehash "^2.0.8"
+ solc "^0.4.20"
+ testrpc "0.0.1"
+ web3-utils "^1.0.0-beta.31"
-"@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.0":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.2.tgz#7ed4a95bb45ee502cf4532223833740a83602797"
- integrity sha512-MbroXutc0gPNYIrUjS4Aw0lDuXabdzI7+l7elRWr1G6G+W0v00e/3gbikWkCReGtt2Jnt4lQSgnflhDwQGcIhA==
+"@ensdomains/ensjs@^2.0.1":
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460"
+ integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==
dependencies:
- "@ethersproject/bytes" "^5.0.0"
- js-sha3 "0.5.7"
+ "@babel/runtime" "^7.4.4"
+ "@ensdomains/address-encoder" "^0.1.7"
+ "@ensdomains/ens" "0.4.5"
+ "@ensdomains/resolver" "0.2.4"
+ content-hash "^2.5.2"
+ eth-ens-namehash "^2.0.8"
+ ethers "^5.0.13"
+ js-sha3 "^0.8.0"
-"@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.0":
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.4.tgz#09fa4765b5691233e3afb6617cb38a700f9dd2e4"
- integrity sha512-alA2LiAy1LdQ/L1SA9ajUC7MvGAEQLsICEfKK4erX5qhkXE1LwLSPIzobtOWFsMHf2yrXGKBLnnpuVHprI3sAw==
+"@ensdomains/resolver@0.2.4":
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89"
+ integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==
-"@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.0":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.2.tgz#2facb62d2f2d968c7b3d0befa5bcc884cc565d3b"
- integrity sha512-FxAisPGAOACQjMJzewl9OJG6lsGCPTm5vpUMtfeoxzAlAb2lv+kHzQPUh9h4jfAILzE8AR1jgXMzRmlhwyra1Q==
+"@eslint/eslintrc@^0.4.3":
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
+ integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
dependencies:
- "@ethersproject/logger" "^5.0.0"
+ ajv "^6.12.4"
+ debug "^4.1.1"
+ espree "^7.3.0"
+ globals "^13.9.0"
+ ignore "^4.0.6"
+ import-fresh "^3.2.1"
+ js-yaml "^3.13.1"
+ minimatch "^3.0.4"
+ strip-json-comments "^3.1.1"
-"@ethersproject/rlp@^5.0.0":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.2.tgz#d6b550a2ac5e484f15f0f63337e522004d2e78cd"
- integrity sha512-oE0M5jqQ67fi2SuMcrpoewOpEuoXaD8M9JeR9md1bXRMvDYgKXUtDHs22oevpEOdnO2DPIRabp6MVHa4aDuWmw==
+"@ethereumjs/common@2.5.0":
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268"
+ integrity sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==
dependencies:
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
+ crc-32 "^1.2.0"
+ ethereumjs-util "^7.1.1"
-"@ethersproject/signing-key@^5.0.0":
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.3.tgz#adb84360e147bfd336cb2fe114100120732dc10a"
- integrity sha512-5QPZaBRGCLzfVMbFb3LcVjNR0UbTXnwDHASnQYfbzwUOnFYHKxHsrcbl/5ONGoppgi8yXgOocKqlPCFycJJVWQ==
+"@ethereumjs/common@^2.5.0":
+ version "2.6.5"
+ resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30"
+ integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==
dependencies:
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
- "@ethersproject/properties" "^5.0.0"
- elliptic "6.5.3"
+ crc-32 "^1.2.0"
+ ethereumjs-util "^7.1.5"
-"@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.0":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.2.tgz#1753408c3c889813fd0992abd76393e3e47a2619"
- integrity sha512-oNa+xvSqsFU96ndzog0IBTtsRFGOqGpzrXJ7shXLBT7juVeSEyZA/sYs0DMZB5mJ9FEjHdZKxR/rTyBY91vuXg==
+"@ethereumjs/rlp@^4.0.1":
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41"
+ integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==
+
+"@ethereumjs/tx@3.3.2":
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.2.tgz#348d4624bf248aaab6c44fec2ae67265efe3db00"
+ integrity sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==
dependencies:
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/constants" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
+ "@ethereumjs/common" "^2.5.0"
+ ethereumjs-util "^7.1.2"
-"@ethersproject/transactions@^5.0.0-beta.135":
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.2.tgz#590ede71fc87b45be7bd46002e18ae52246a2347"
- integrity sha512-jZp0ZbbJlq4JLZY6qoMzNtp2HQsX6USQposi3ns0MPUdn3OdZJBDtrcO15r/2VS5t/K1e1GE5MI1HmMKlcTbbQ==
- dependencies:
- "@ethersproject/address" "^5.0.0"
- "@ethersproject/bignumber" "^5.0.0"
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/constants" "^5.0.0"
- "@ethersproject/keccak256" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
- "@ethersproject/properties" "^5.0.0"
- "@ethersproject/rlp" "^5.0.0"
- "@ethersproject/signing-key" "^5.0.0"
-
-"@nodelib/fs.scandir@2.1.3":
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
- integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==
+"@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.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.6.3", "@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.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.6.2", "@ethersproject/transactions@^5.7.0":
+ version "5.7.0"
+ resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b"
+ integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==
+ 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"
+
+"@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.5.0":
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
+ integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.0"
+ debug "^4.1.1"
+ minimatch "^3.0.4"
+
+"@humanwhocodes/object-schema@^1.2.0":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
+ integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
+
+"@jridgewell/resolve-uri@^3.0.3":
+ 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.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"
+ 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"
+
+"@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"
+
+"@multiformats/base-x@^4.0.1":
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@multiformats/base-x/-/base-x-4.0.1.tgz#95ff0fa58711789d53aefb2590a8b7a4e715d121"
+ integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==
+
+"@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/curves@1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35"
+ integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==
+ dependencies:
+ "@noble/hashes" "1.3.2"
+
+"@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/hashes@1.3.1", "@noble/hashes@~1.3.0", "@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.2":
+ 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"
+ 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.3"
+ "@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
-"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2":
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3"
- integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==
+"@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":
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976"
- integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==
+ 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.3"
+ "@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
-"@openzeppelin/contracts@^3.1.0":
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.1.0.tgz#bcea457ef89069fbe5a617f50b25b6a8272895d5"
- integrity sha512-dVXDnUKxrAKLzPdCRkz+N8qsVkK1XxJ6kk3zuI6zaQmcKxN7CkizoDP7lXxcs/Mi2I0mxceTRjJBqlzFffLJrQ==
+"@nomicfoundation/ethereumjs-block@5.0.2":
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04"
+ integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q==
+ dependencies:
+ "@nomicfoundation/ethereumjs-common" "4.0.2"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ "@nomicfoundation/ethereumjs-trie" "6.0.2"
+ "@nomicfoundation/ethereumjs-tx" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ ethereum-cryptography "0.1.3"
+ ethers "^5.7.1"
+
+"@nomicfoundation/ethereumjs-blockchain@7.0.2":
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446"
+ integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w==
+ dependencies:
+ "@nomicfoundation/ethereumjs-block" "5.0.2"
+ "@nomicfoundation/ethereumjs-common" "4.0.2"
+ "@nomicfoundation/ethereumjs-ethash" "3.0.2"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ "@nomicfoundation/ethereumjs-trie" "6.0.2"
+ "@nomicfoundation/ethereumjs-tx" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ 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.2":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3"
+ integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg==
+ dependencies:
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ crc-32 "^1.2.0"
-"@sindresorhus/is@^0.14.0":
- version "0.14.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
- integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
+"@nomicfoundation/ethereumjs-ethash@3.0.2":
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca"
+ integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg==
+ dependencies:
+ "@nomicfoundation/ethereumjs-block" "5.0.2"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ abstract-level "^1.0.3"
+ bigint-crypto-utils "^3.0.23"
+ ethereum-cryptography "0.1.3"
+
+"@nomicfoundation/ethereumjs-evm@2.0.2":
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6"
+ integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ==
+ dependencies:
+ "@ethersproject/providers" "^5.7.1"
+ "@nomicfoundation/ethereumjs-common" "4.0.2"
+ "@nomicfoundation/ethereumjs-tx" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ debug "^4.3.3"
+ ethereum-cryptography "0.1.3"
+ mcl-wasm "^0.7.1"
+ rustbn.js "~0.2.0"
+
+"@nomicfoundation/ethereumjs-rlp@5.0.2":
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea"
+ integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA==
+
+"@nomicfoundation/ethereumjs-statemanager@2.0.2":
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0"
+ integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA==
+ dependencies:
+ "@nomicfoundation/ethereumjs-common" "4.0.2"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ debug "^4.3.3"
+ ethereum-cryptography "0.1.3"
+ ethers "^5.7.1"
+ js-sdsl "^4.1.4"
+
+"@nomicfoundation/ethereumjs-trie@6.0.2":
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835"
+ integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ==
+ dependencies:
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ "@types/readable-stream" "^2.3.13"
+ ethereum-cryptography "0.1.3"
+ readable-stream "^3.6.0"
+
+"@nomicfoundation/ethereumjs-tx@5.0.2":
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56"
+ integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g==
+ dependencies:
+ "@chainsafe/ssz" "^0.9.2"
+ "@ethersproject/providers" "^5.7.2"
+ "@nomicfoundation/ethereumjs-common" "4.0.2"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ ethereum-cryptography "0.1.3"
+
+"@nomicfoundation/ethereumjs-util@9.0.2":
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d"
+ integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ==
+ dependencies:
+ "@chainsafe/ssz" "^0.10.0"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ ethereum-cryptography "0.1.3"
+
+"@nomicfoundation/ethereumjs-vm@7.0.2":
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6"
+ integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA==
+ dependencies:
+ "@nomicfoundation/ethereumjs-block" "5.0.2"
+ "@nomicfoundation/ethereumjs-blockchain" "7.0.2"
+ "@nomicfoundation/ethereumjs-common" "4.0.2"
+ "@nomicfoundation/ethereumjs-evm" "2.0.2"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ "@nomicfoundation/ethereumjs-statemanager" "2.0.2"
+ "@nomicfoundation/ethereumjs-trie" "6.0.2"
+ "@nomicfoundation/ethereumjs-tx" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ debug "^4.3.3"
+ ethereum-cryptography "0.1.3"
+ mcl-wasm "^0.7.1"
+ rustbn.js "~0.2.0"
+
+"@nomicfoundation/hardhat-chai-matchers@2.0.2":
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.2.tgz#a0e5dbca43ba9560c096da162c0e3245303479d1"
+ integrity sha512-9Wu9mRtkj0U9ohgXYFbB/RQDa+PcEdyBm2suyEtsJf3PqzZEEjLUZgWnMjlFhATMk/fp3BjmnYVPrwl+gr8oEw==
+ dependencies:
+ "@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-foundry@1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-foundry/-/hardhat-foundry-1.1.1.tgz#db72b1f33f9cfaecc27e67f69ad436f8710162d6"
+ integrity sha512-cXGCBHAiXas9Pg9MhMOpBVQCkWRYoRFG7GJJAph+sdQsfd22iRs5U5Vs9XmpGEQd1yEvYISQZMeE68Nxj65iUQ==
+ dependencies:
+ chalk "^2.4.2"
+
+"@nomicfoundation/hardhat-network-helpers@1.0.8":
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz#e4fe1be93e8a65508c46d73c41fa26c7e9f84931"
+ integrity sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==
+ dependencies:
+ ethereumjs-util "^7.1.4"
+
+"@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-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-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-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-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-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-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.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.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-truffle5@2.0.7":
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.7.tgz#7519eadd2c6c460c2addc3d4d6efda7a8883361e"
+ integrity sha512-Pw8451IUZp1bTp0QqCHCYfCHs66sCnyxPcaorapu9mfOV9xnZsVaFdtutnhNEiXdiZwbed7LFKpRsde4BjFwig==
+ dependencies:
+ "@nomiclabs/truffle-contract" "^4.2.23"
+ "@types/chai" "^4.2.0"
+ chai "^4.2.0"
+ ethereumjs-util "^7.1.4"
+ fs-extra "^7.0.1"
+
+"@nomiclabs/hardhat-web3@2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz#2d9850cb285a2cebe1bd718ef26a9523542e52a9"
+ integrity sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==
+ dependencies:
+ "@types/bignumber.js" "^5.0.0"
+
+"@nomiclabs/truffle-contract@^4.2.23":
+ version "4.5.10"
+ resolved "https://registry.yarnpkg.com/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz#52adcca1068647e1c2b44bf0e6a89fc4ad7f9213"
+ integrity sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ==
+ dependencies:
+ "@ensdomains/ensjs" "^2.0.1"
+ "@truffle/blockchain-utils" "^0.1.3"
+ "@truffle/contract-schema" "^3.4.7"
+ "@truffle/debug-utils" "^6.0.22"
+ "@truffle/error" "^0.1.0"
+ "@truffle/interface-adapter" "^0.5.16"
+ bignumber.js "^7.2.1"
+ ethereum-ens "^0.8.0"
+ ethers "^4.0.0-beta.1"
+ source-map-support "^0.5.19"
+
+"@openzeppelin/contracts@3.4.2":
+ version "3.4.2"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527"
+ integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA==
+
+"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
+ integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
+
+"@protobufjs/base64@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
+ integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
+
+"@protobufjs/codegen@^2.0.4":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
+ integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
+
+"@protobufjs/eventemitter@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
+ integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
+
+"@protobufjs/fetch@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
+ integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
+ dependencies:
+ "@protobufjs/aspromise" "^1.1.1"
+ "@protobufjs/inquire" "^1.1.0"
-"@solidity-parser/parser@^0.6.0", "@solidity-parser/parser@^0.6.2":
+"@protobufjs/float@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
+ integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
+
+"@protobufjs/inquire@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
+ integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
+
+"@protobufjs/path@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
+ integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
+
+"@protobufjs/pool@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
+ integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
+
+"@protobufjs/utf8@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
+ integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
+
+"@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.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.2.0"
+ "@noble/secp256k1" "~1.7.0"
+ "@scure/base" "~1.1.0"
+
+"@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/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":
+ 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"
+
+"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0":
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
+ integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
+
+"@sinonjs/commons@^3.0.1":
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd"
+ integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==
+ dependencies:
+ type-detect "4.0.8"
+
+"@sinonjs/fake-timers@^13.0.1", "@sinonjs/fake-timers@^13.0.2":
+ version "13.0.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz#3ffe88abb062067a580fdfba706ad00435a0f2a6"
+ integrity sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==
+ dependencies:
+ "@sinonjs/commons" "^3.0.1"
+
+"@sinonjs/samsam@^8.0.1":
+ version "8.0.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.2.tgz#e4386bf668ff36c95949e55a38dc5f5892fc2689"
+ integrity sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==
+ dependencies:
+ "@sinonjs/commons" "^3.0.1"
+ lodash.get "^4.4.2"
+ type-detect "^4.1.0"
+
+"@sinonjs/text-encoding@^0.7.3":
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz#282046f03e886e352b2d5f5da5eb755e01457f3f"
+ integrity sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==
+
+"@solidity-parser/parser@^0.14.0":
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804"
+ integrity sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==
+ 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==
+ dependencies:
+ antlr4ts "^0.5.0-alpha.4"
+
+"@solidity-parser/parser@^0.18.0":
+ version "0.18.0"
+ resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.18.0.tgz#8e77a02a09ecce957255a2f48c9a7178ec191908"
+ integrity sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==
+
+"@solidity-parser/parser@^0.6.2":
version "0.6.2"
resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.6.2.tgz#49707fc4e06649d39d6b25bdab2e9093d372ce50"
integrity sha512-kUVUvrqttndeprLoXjI5arWHeiP3uh4XODAKbG+ZaWHCVQeelxCbnXBeWxZ2BPHdXgH0xR9dU1b916JhDhbgAA==
-"@szmarczak/http-timer@^1.1.2":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
- integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
+"@szmarczak/http-timer@^4.0.5":
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
+ integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==
dependencies:
- defer-to-connect "^1.0.1"
+ defer-to-connect "^2.0.0"
-"@truffle/error@^0.0.7":
- version "0.0.7"
- resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.0.7.tgz#e9db39885575647ef08bf624b0c13fe46d41a209"
- integrity sha512-UIfVKsXSXocKnn5+RNklUXNoGd/JVj7V8KmC48TQzmjU33HQI86PX0JDS7SpHMHasI3w9X//1q7Lu7nZtj3Zzg==
+"@szmarczak/http-timer@^5.0.1":
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a"
+ integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==
+ dependencies:
+ defer-to-connect "^2.0.1"
-"@truffle/hdwallet-provider@^1.0.39":
- version "1.0.39"
- resolved "https://registry.yarnpkg.com/@truffle/hdwallet-provider/-/hdwallet-provider-1.0.39.tgz#7664102db9b25312f34703fcb353fb9c3f0f19a4"
- integrity sha512-xLe+FrAAU3nbSfPoCD4xr4qUkUx6xZOfsn9E/KRJewCBDVzQ/0DfyOC8++SDXvgu+ftgGKZjOucP/QHfRRtIjg==
+"@truffle/abi-utils@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-1.0.2.tgz#41210b234912051433960382af009f339f8a9642"
+ integrity sha512-MefEcxsBlprKIpfW7eh2I5zJqlWM18xk3duL7SW4VhIs6kNEec//hCpEDoE6P0m7GjqY3vk8X4vnf4aLlZkRcA==
dependencies:
- "@trufflesuite/web3-provider-engine" "15.0.0-2"
- any-promise "^1.3.0"
- bindings "^1.5.0"
- ethereum-cryptography "^0.1.3"
- ethereum-protocol "^1.0.1"
- ethereumjs-tx "^1.0.0"
- ethereumjs-util "^6.1.0"
- ethereumjs-wallet "^0.6.3"
- source-map-support "^0.5.19"
- web3 "1.2.1"
+ change-case "3.0.2"
+ fast-check "3.1.1"
+ web3-utils "1.10.0"
-"@truffle/interface-adapter@^0.3.0":
- version "0.3.3"
- resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.3.3.tgz#61305378cf81776769ef36c60d394e568ac4a2ee"
- integrity sha512-l3I4WFTfnBSIfG96IOBRtAIE6AHDAxcOUJE7W5zh9hocQwzQlGWc2yEyyTcLa0656TTM8RxaZZ2S/KdHHMvCaw==
+"@truffle/blockchain-utils@^0.1.3":
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.1.8.tgz#0c1a369aa72f51df5af095678803242ea0a0d6ae"
+ integrity sha512-ZskpYDNHkXD3ota4iU3pZz6kLth87RC+wDn66Rp2Or+DqqJCKdnmS9GDctBi1EcMPDEi0BqpkdrfBuzA9uIkGg==
+
+"@truffle/codec@^0.17.2":
+ version "0.17.2"
+ resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.17.2.tgz#52a3604f73b89964373eec945f20d5cd0f4244d4"
+ integrity sha512-n9HX8R5a5+/j6Y0+lqSzIyU1cUxTRYn/xEWp0Qc1b0Vtltad7wvVh+KLGvbm/KQEX3o1RK1xRIUN2E0QlDeQnA==
+ dependencies:
+ "@truffle/abi-utils" "^1.0.2"
+ "@truffle/compile-common" "^0.9.7"
+ big.js "^6.0.3"
+ bn.js "^5.1.3"
+ cbor "^5.2.0"
+ debug "^4.3.1"
+ lodash "^4.17.21"
+ semver "7.5.2"
+ utf8 "^3.0.0"
+ web3-utils "1.10.0"
+
+"@truffle/compile-common@^0.9.7":
+ version "0.9.7"
+ resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.9.7.tgz#e8ba6cd49c4d4e7ae4684ba453fb9b2dcd09b347"
+ integrity sha512-TXuVLc5yJ/A0bSWw5OWIdXmcyaPpj3TJQ60ki7w9cIuW65Bazw7P4FRPaVNjR9YGe1FLYJ36GSdd9V3egPbzCg==
dependencies:
- bn.js "^4.11.8"
+ "@truffle/error" "^0.2.1"
+ colors "1.4.0"
+
+"@truffle/contract-schema@^3.4.7":
+ version "3.4.15"
+ resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.4.15.tgz#199789b3f0a61b0e564ee8d62d7a7e5a8e6b749f"
+ integrity sha512-m13e1VlXEdxiXiqv/SmPlqbdtcuhjwIGTICm+JCEO8nt0NYBbdMC2paNkpUvGz9lK139JxIupMHctEV4vgkldw==
+ dependencies:
+ ajv "^6.10.0"
+ debug "^4.3.1"
+
+"@truffle/debug-utils@^6.0.22":
+ version "6.0.56"
+ resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.56.tgz#7727891580c52cc9acfbe46d43ca4ef9aa338713"
+ integrity sha512-tCB0nKZirWlQp+0JqqaBxZk7CIwDBIHl8Q9CyGJZA4pdAwKHHMI3FoPAXzubP7X0YuICeQsAmpOAXzOHGYGkjg==
+ dependencies:
+ "@truffle/codec" "^0.17.2"
+ "@trufflesuite/chromafi" "^3.0.0"
+ bn.js "^5.1.3"
+ chalk "^2.4.2"
+ debug "^4.3.1"
+ highlightjs-solidity "^2.0.6"
+
+"@truffle/error@^0.1.0":
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.1.1.tgz#e52026ac8ca7180d83443dca73c03e07ace2a301"
+ integrity sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==
+
+"@truffle/error@^0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.2.1.tgz#71bb8e777a832e0cfe09a8638a70a5177aad8628"
+ integrity sha512-5Qy+z9dg9hP37WNdLnXH4b9MzemWrjTufRq7/DTKqimjyxCP/1zlL8gQEMdiSx1BBtAZz0xypkID/jb7AF/Osg==
+
+"@truffle/interface-adapter@^0.5.16":
+ version "0.5.35"
+ resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.35.tgz#f0eb1c4a2803190ca249143f545029a8b641fe96"
+ integrity sha512-B5gtJnvsum5j2do393n0UfCT8MklrlAZxuqvEFBeMM9UKnreYct0/D368FVMlZwWo1N50HgGeZ0hlpSJqR/nvg==
+ dependencies:
+ bn.js "^5.1.3"
ethers "^4.0.32"
- lodash "^4.17.13"
- web3 "1.2.2"
-
-"@truffle/provider@^0.1.17":
- version "0.1.19"
- resolved "https://registry.yarnpkg.com/@truffle/provider/-/provider-0.1.19.tgz#3e6f15fdd8475ca5d0c846d2b412cc823f1fb767"
- integrity sha512-ke8iQmzW4Y99+8iff8xQcc+mCNU4AkwtaZ/iSpmVD8qpLytw8/DSNCm0RiEz9/+I93Q1zqI4Jnij/rXnkS2Njw==
- dependencies:
- "@truffle/error" "^0.0.7"
- "@truffle/interface-adapter" "^0.3.0"
- web3 "1.2.1"
-
-"@trufflesuite/eth-json-rpc-filters@^4.1.2-1":
- version "4.1.2-1"
- resolved "https://registry.yarnpkg.com/@trufflesuite/eth-json-rpc-filters/-/eth-json-rpc-filters-4.1.2-1.tgz#61ab78c52e98a883e5cf086925b34a30297b1824"
- integrity sha512-/MChvC5dw2ck9NU1cZmdovCz2VKbOeIyR4tcxDvA5sT+NaL0rA2/R5U0yI7zsbo1zD+pgqav77rQHTzpUdDNJQ==
- dependencies:
- "@trufflesuite/eth-json-rpc-middleware" "^4.4.2-0"
- await-semaphore "^0.1.3"
- eth-query "^2.1.2"
- json-rpc-engine "^5.1.3"
- lodash.flatmap "^4.5.0"
- safe-event-emitter "^1.0.1"
-
-"@trufflesuite/eth-json-rpc-middleware@^4.4.2-0", "@trufflesuite/eth-json-rpc-middleware@^4.4.2-1":
- version "4.4.2-1"
- resolved "https://registry.yarnpkg.com/@trufflesuite/eth-json-rpc-middleware/-/eth-json-rpc-middleware-4.4.2-1.tgz#8c3638ed8a7ed89a1e5e71407de068a65bef0df2"
- integrity sha512-iEy9H8ja7/8aYES5HfrepGBKU9n/Y4OabBJEklVd/zIBlhCCBAWBqkIZgXt11nBXO/rYAeKwYuE3puH3ByYnLA==
- dependencies:
- "@trufflesuite/eth-sig-util" "^1.4.2"
- btoa "^1.2.1"
- clone "^2.1.1"
- eth-json-rpc-errors "^1.0.1"
- eth-query "^2.1.2"
- ethereumjs-block "^1.6.0"
- ethereumjs-tx "^1.3.7"
- ethereumjs-util "^5.1.2"
- ethereumjs-vm "^2.6.0"
- fetch-ponyfill "^4.0.0"
- json-rpc-engine "^5.1.3"
- json-stable-stringify "^1.0.1"
- pify "^3.0.0"
- safe-event-emitter "^1.0.1"
-
-"@trufflesuite/eth-sig-util@^1.4.2":
- version "1.4.2"
- resolved "https://registry.yarnpkg.com/@trufflesuite/eth-sig-util/-/eth-sig-util-1.4.2.tgz#b529e2f38ac08e652116f48981132a26242a4f08"
- integrity sha512-+GyfN6b0LNW77hbQlH3ufZ/1eCON7mMrGym6tdYf7xiNw9Vv3jBO72bmmos1EId2NgBvPMhmYYm6DSLQFTmzrA==
+ web3 "1.10.0"
+
+"@trufflesuite/chromafi@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz#f6956408c1af6a38a6ed1657783ce59504a1eb8b"
+ integrity sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==
+ dependencies:
+ camelcase "^4.1.0"
+ chalk "^2.3.2"
+ cheerio "^1.0.0-rc.2"
+ detect-indent "^5.0.0"
+ highlight.js "^10.4.1"
+ lodash.merge "^4.6.2"
+ strip-ansi "^4.0.0"
+ strip-indent "^2.0.0"
+
+"@tsconfig/node10@^1.0.7":
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
+ 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.4"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
+ integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
+
+"@typechain/ethers-v6@0.4.3":
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/@typechain/ethers-v6/-/ethers-v6-0.4.3.tgz#badd99f88d5a1f1a2f42590f298e20cc62618e59"
+ integrity sha512-TrxBsyb4ryhaY9keP6RzhFCviWYApcLCIRMPyWaKp2cZZrfaM3QBoxXTnw/eO4+DAY3l+8O0brNW0WgeQeOiDA==
dependencies:
- ethereumjs-abi "^0.6.8"
- ethereumjs-util "^5.1.1"
-
-"@trufflesuite/web3-provider-engine@15.0.0-2":
- version "15.0.0-2"
- resolved "https://registry.yarnpkg.com/@trufflesuite/web3-provider-engine/-/web3-provider-engine-15.0.0-2.tgz#0e9a581cfda6b82ab8224883859a954b5ee5fb66"
- integrity sha512-rBktH8MkEL5xrdI9YJIuaOEr0emEpWzw/5ZXRUWJxrxc/GE/v5n10JR8MeKK9g9IRWc9rFFb8u4ac2rvoDBzzQ==
- dependencies:
- "@trufflesuite/eth-json-rpc-filters" "^4.1.2-1"
- "@trufflesuite/eth-json-rpc-middleware" "^4.4.2-1"
- "@trufflesuite/eth-sig-util" "^1.4.2"
- async "^2.5.0"
- backoff "^2.5.0"
- clone "^2.0.0"
- cross-fetch "^2.1.0"
- eth-block-tracker "^4.2.0"
- eth-json-rpc-infura "^3.1.0"
- ethereumjs-block "^1.2.2"
- ethereumjs-tx "^1.2.0"
- ethereumjs-util "^5.1.5"
- ethereumjs-vm "^2.3.4"
- json-rpc-error "^2.0.0"
- json-stable-stringify "^1.0.1"
- promise-to-callback "^1.0.0"
- readable-stream "^2.2.9"
- request "^2.85.0"
- semaphore "^1.0.3"
- ws "^5.1.1"
- xhr "^2.2.0"
- xtend "^4.0.1"
-
-"@typechain/truffle-v5@^2.0.2":
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/@typechain/truffle-v5/-/truffle-v5-2.0.2.tgz#709a78ffb120f52c693818fea72e0b0d146c3454"
- integrity sha512-g4N2kfol1S3g/QUkmpzukCGZiKWUdXsSms1be/+W4+R0DPMz1Q/76tY+C6bD7G/KeLhkiDKcnZFmNVNcAgjIfQ==
+ lodash "^4.17.15"
+ ts-essentials "^7.0.1"
-"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4", "@types/bn.js@^4.11.5":
+"@typechain/hardhat@9.0.0":
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-9.0.0.tgz#c92d562566db9b933ac6899c0a0a2ae1871ad5c1"
+ integrity sha512-oCGRvcsryRHEDZ4KO2lenB7wdf8WMDS+f9KGcRFiQWcRLpWWD0ruBGRxNjzkTqyPLtgQ9MvZsXquAFPEw7gAEA==
+ dependencies:
+ fs-extra "^9.1.0"
+
+"@typechain/truffle-v5@8.0.6":
+ version "8.0.6"
+ resolved "https://registry.yarnpkg.com/@typechain/truffle-v5/-/truffle-v5-8.0.6.tgz#59019bbf990efca699c0fe6fb81ec9ab68e32757"
+ integrity sha512-0G8rAQVpJcW2rCJUMBfq/D4FxWk3sBwxzywUYQc0vngV514Yv1JtU8L3W0lNjXoDRjABdNzksrZ0He6IcxFDpw==
+ dependencies:
+ lodash "^4.17.15"
+
+"@types/bignumber.js@^5.0.0":
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969"
+ integrity sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==
+ dependencies:
+ bignumber.js "*"
+
+"@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/chai@^4.2.11":
- version "4.2.11"
- resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.11.tgz#d3614d6c5f500142358e6ed24e1bf16657536c50"
- integrity sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==
+"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1":
+ 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/color-name@^1.1.1":
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
- integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
+"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2":
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183"
+ integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==
+ dependencies:
+ "@types/http-cache-semantics" "*"
+ "@types/keyv" "^3.1.4"
+ "@types/node" "*"
+ "@types/responselike" "^1.0.0"
+
+"@types/chai-as-promised@^7.1.3":
+ version "7.1.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.3.5", "@types/chai@^4.2.0":
+ version "4.3.5"
+ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.5.tgz#ae69bcbb1bebb68c4ac0b11e9d8ed04526b3562b"
+ integrity sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==
+
+"@types/concat-stream@^1.6.0":
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/@types/concat-stream/-/concat-stream-1.6.1.tgz#24bcfc101ecf68e886aaedce60dfd74b632a1b74"
+ integrity sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==
+ dependencies:
+ "@types/node" "*"
"@types/eslint-visitor-keys@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
+"@types/ethereumjs-abi@0.6.3":
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/@types/ethereumjs-abi/-/ethereumjs-abi-0.6.3.tgz#eb5ed09fd86b9e2b1c0eb75d1e9bc29c50715c86"
+ integrity sha512-DnHvqPkrJS5w4yZexTa5bdPNb8IyKPYciou0+zZCIg5fpzvGtyptTvshy0uZKzti2/k/markwjlxWRBWt7Mjuw==
+ dependencies:
+ "@types/node" "*"
+
+"@types/form-data@0.0.33":
+ version "0.0.33"
+ resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8"
+ integrity sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==
+ dependencies:
+ "@types/node" "*"
+
"@types/glob@^7.1.1":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
- integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
+ integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
dependencies:
"@types/minimatch" "*"
"@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==
+
"@types/json-schema@^7.0.3":
- version "7.0.5"
- resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
- integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
+ version "7.0.12"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb"
+ integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
- integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
+ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
-"@types/lodash@^4.14.158":
- version "4.14.158"
- resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.158.tgz#b38ea8b6fe799acd076d7a8d7ab71c26ef77f785"
- integrity sha512-InCEXJNTv/59yO4VSfuvNrZHt7eeNtWQEgnieIA+mIC+MOWM9arOWG2eQ8Vhk6NbOre6/BidiXhkZYeDY9U35w==
-
-"@types/minimatch@*":
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
- integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
-
-"@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==
+"@types/keyv@^3.1.4":
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6"
+ integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==
dependencies:
"@types/node" "*"
-"@types/mocha@^8.0.0":
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.0.0.tgz#b0ba1c5b4cb3880c51a6b488ad007a657d1be888"
- integrity sha512-jWeYcTo3sCH/rMgsdYXDTO85GNRyTCII5dayMIu/ZO4zbEot1E3iNGaOwpLReLUHjeNQFkgeNNVYlY4dX6azQQ==
+"@types/lodash@4.14.195":
+ version "4.14.195"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632"
+ integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==
-"@types/node@*":
- version "14.0.24"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.24.tgz#b0f86f58564fa02a28b68f8b55d4cdec42e3b9d6"
- integrity sha512-btt/oNOiDWcSuI721MdL8VQGnjsKjlTMdrKyTcLCKeQp/n4AAMFJ961wMbp+09y8WuGPClDEv07RIItdXKIXAA==
+"@types/long@^4.0.1":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
+ integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
+
+"@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/minimatch@*":
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
+ integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==
+
+"@types/minimist@^1.2.0":
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e"
+ integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==
-"@types/node@^10.12.18", "@types/node@^10.3.2":
- version "10.17.27"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.27.tgz#391cb391c75646c8ad2a7b6ed3bbcee52d1bdf19"
- integrity sha512-J0oqm9ZfAXaPdwNXMMgAhylw5fhmXkToJd06vuDUSAgEDZ/n/69/69UmyBZbc+zT34UnShuDSBqvim3SPnozJg==
+"@types/mocha@10.0.1":
+ version "10.0.1"
+ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b"
+ integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==
-"@types/node@^12.12.6", "@types/node@^12.6.1":
- version "12.12.51"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.51.tgz#446a67af8c5ff98947d7cef296484c6ad47ddb16"
- integrity sha512-6ILqt8iNThALrxDv2Q4LyYFQxULQz96HKNIFd4s9QRQaiHINYeUpLqeU/2IU7YMtvipG1fQVAy//vY8/fX1Y9w==
+"@types/node@*":
+ version "20.4.2"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9"
+ integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==
+
+"@types/node@18.15.13":
+ version "18.15.13"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
+ integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
+
+"@types/node@20.5.1":
+ version "20.5.1"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30"
+ integrity sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==
+
+"@types/node@>=13.7.0":
+ version "22.1.0"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-22.1.0.tgz#6d6adc648b5e03f0e83c78dc788c2b037d0ad94b"
+ integrity sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==
+ dependencies:
+ undici-types "~6.13.0"
+
+"@types/node@^10.0.3":
+ version "10.17.60"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
+ integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==
+
+"@types/node@^12.12.6":
+ version "12.20.55"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
+ integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
+
+"@types/node@^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/normalize-package-data@^2.4.0":
+ version "2.4.4"
+ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901"
+ integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==
"@types/pbkdf2@^3.0.0":
version "3.1.0"
@@ -423,71 +1459,96 @@
dependencies:
"@types/node" "*"
-"@types/prettier@^1.13.2":
- version "1.19.1"
- resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f"
- integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==
+"@types/prettier@^2.1.1":
+ 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==
+
+"@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==
+"@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==
dependencies:
"@types/node" "*"
"@types/secp256k1@^4.0.1":
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.1.tgz#fb3aa61a1848ad97d7425ff9dcba784549fca5a4"
- integrity sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==
+ 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" "*"
-"@typescript-eslint/eslint-plugin@^3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.0.tgz#0f91aa3c83d019591719e597fbdb73a59595a263"
- integrity sha512-4OEcPON3QIx0ntsuiuFP/TkldmBGXf0uKxPQlGtS/W2F3ndYm8Vgdpj/woPJkzUc65gd3iR+qi3K8SDQP/obFg==
+"@types/sinon@17.0.3":
+ version "17.0.3"
+ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-17.0.3.tgz#9aa7e62f0a323b9ead177ed23a36ea757141a5fa"
+ integrity sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==
dependencies:
- "@typescript-eslint/experimental-utils" "3.7.0"
+ "@types/sinonjs__fake-timers" "*"
+
+"@types/sinonjs__fake-timers@*":
+ version "8.1.5"
+ resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz#5fd3592ff10c1e9695d377020c033116cc2889f2"
+ integrity sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==
+
+"@typescript-eslint/eslint-plugin@3.10.1":
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz#7e061338a1383f59edc204c605899f93dc2e2c8f"
+ integrity sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==
+ dependencies:
+ "@typescript-eslint/experimental-utils" "3.10.1"
debug "^4.1.1"
functional-red-black-tree "^1.0.1"
regexpp "^3.0.0"
semver "^7.3.2"
tsutils "^3.17.1"
-"@typescript-eslint/experimental-utils@3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.0.tgz#0ee21f6c48b2b30c63211da23827725078d5169a"
- integrity sha512-xpfXXAfZqhhqs5RPQBfAFrWDHoNxD5+sVB5A46TF58Bq1hRfVROrWHcQHHUM9aCBdy9+cwATcvCbRg8aIRbaHQ==
+"@typescript-eslint/experimental-utils@3.10.1":
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686"
+ integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==
dependencies:
"@types/json-schema" "^7.0.3"
- "@typescript-eslint/types" "3.7.0"
- "@typescript-eslint/typescript-estree" "3.7.0"
+ "@typescript-eslint/types" "3.10.1"
+ "@typescript-eslint/typescript-estree" "3.10.1"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
-"@typescript-eslint/parser@^3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.7.0.tgz#3e9cd9df9ea644536feb6e5acdb8279ecff96ce9"
- integrity sha512-2LZauVUt7jAWkcIW7djUc3kyW+fSarNEuM3RF2JdLHR9BfX/nDEnyA4/uWz0wseoWVZbDXDF7iF9Jc342flNqQ==
+"@typescript-eslint/parser@3.10.1":
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.10.1.tgz#1883858e83e8b442627e1ac6f408925211155467"
+ integrity sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==
dependencies:
"@types/eslint-visitor-keys" "^1.0.0"
- "@typescript-eslint/experimental-utils" "3.7.0"
- "@typescript-eslint/types" "3.7.0"
- "@typescript-eslint/typescript-estree" "3.7.0"
+ "@typescript-eslint/experimental-utils" "3.10.1"
+ "@typescript-eslint/types" "3.10.1"
+ "@typescript-eslint/typescript-estree" "3.10.1"
eslint-visitor-keys "^1.1.0"
-"@typescript-eslint/types@3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.7.0.tgz#09897fab0cb95479c01166b10b2c03c224821077"
- integrity sha512-reCaK+hyKkKF+itoylAnLzFeNYAEktB0XVfSQvf0gcVgpz1l49Lt6Vo9x4MVCCxiDydA0iLAjTF/ODH0pbfnpg==
+"@typescript-eslint/types@3.10.1":
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727"
+ integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==
-"@typescript-eslint/typescript-estree@3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.0.tgz#66872e6da120caa4b64e6b4ca5c8702afc74738d"
- integrity sha512-xr5oobkYRebejlACGr1TJ0Z/r0a2/HUf0SXqPvlgUMwiMqOCu/J+/Dr9U3T0IxpE5oLFSkqMx1FE/dKaZ8KsOQ==
+"@typescript-eslint/typescript-estree@3.10.1":
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853"
+ integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==
dependencies:
- "@typescript-eslint/types" "3.7.0"
- "@typescript-eslint/visitor-keys" "3.7.0"
+ "@typescript-eslint/types" "3.10.1"
+ "@typescript-eslint/visitor-keys" "3.10.1"
debug "^4.1.1"
glob "^7.1.6"
is-glob "^4.0.1"
@@ -495,157 +1556,165 @@
semver "^7.3.2"
tsutils "^3.17.1"
-"@typescript-eslint/visitor-keys@3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.0.tgz#ac0417d382a136e4571a0b0dcfe52088cb628177"
- integrity sha512-k5PiZdB4vklUpUX4NBncn5RBKty8G3ihTY+hqJsCdMuD0v4jofI5xuqwnVcWxfv6iTm2P/dfEa2wMUnsUY8ODw==
+"@typescript-eslint/visitor-keys@3.10.1":
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931"
+ integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==
dependencies:
eslint-visitor-keys "^1.1.0"
-"@web3-js/scrypt-shim@^0.1.0":
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz#0bf7529ab6788311d3e07586f7d89107c3bea2cc"
- integrity sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw==
- dependencies:
- scryptsy "^2.1.0"
- semver "^6.3.0"
-
-"@web3-js/websocket@^1.0.29":
- version "1.0.30"
- resolved "https://registry.yarnpkg.com/@web3-js/websocket/-/websocket-1.0.30.tgz#9ea15b7b582cf3bf3e8bc1f4d3d54c0731a87f87"
- integrity sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA==
- dependencies:
- debug "^2.2.0"
- es5-ext "^0.10.50"
- nan "^2.14.0"
- typedarray-to-buffer "^3.1.5"
- yaeti "^0.0.6"
-
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
-abbrev@1.0.x:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
- integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU=
-
-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-leveldown@~2.6.0:
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8"
- integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==
- dependencies:
- xtend "~4.0.0"
-
-abstract-leveldown@~2.7.1:
- version "2.7.2"
- resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93"
- integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==
- dependencies:
- xtend "~4.0.0"
+abbrev@1.0.x:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
+ integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==
-accepts@~1.3.7:
- version "1.3.7"
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
- integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
- dependencies:
- mime-types "~2.1.24"
- negotiator "0.6.2"
+abortcontroller-polyfill@^1.7.3:
+ version "1.7.5"
+ resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed"
+ integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==
-acorn-jsx@^5.0.0, acorn-jsx@^5.2.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe"
- integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==
+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"
+
+accepts@~1.3.8:
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
+ integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
+ dependencies:
+ mime-types "~2.1.34"
+ negotiator "0.6.3"
+
+acorn-jsx@^5.3.1:
+ 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@^6.0.7:
- version "6.4.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474"
- integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
+acorn@^7.4.0:
+ version "7.4.1"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
+ integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
-acorn@^7.3.1:
- version "7.3.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd"
- integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==
+acorn@^8.4.1:
+ version "8.10.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
+ integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
-address@^1.0.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
- integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
+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 sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=
+ integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==
-aes-js@^3.1.1:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a"
- integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==
+aes-js@4.0.0-beta.5:
+ version "4.0.0-beta.5"
+ resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873"
+ integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==
agent-base@6:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4"
- integrity sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==
+ 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"
-ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.6.1, ajv@^6.9.1:
- version "6.12.3"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
- integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
+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.10.0, ajv@^6.12.3, 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"
+
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
- integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
+ 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, ansi-colors@^4.1.1:
+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-escapes@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
- integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
+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@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
- integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
+ integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
ansi-regex@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
- integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
+ version "3.0.1"
+ 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.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
- integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
-
-ansi-regex@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
- integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
+ integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
-ansi-styles@^2.2.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
- integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
+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.0, ansi-styles@^3.2.1:
version "3.2.1"
@@ -654,37 +1723,31 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
-ansi-styles@^4.1.0:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
- integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
+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:
- "@types/color-name" "^1.1.1"
color-convert "^2.0.1"
-antlr4@4.7.1:
- version "4.7.1"
- resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773"
- integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==
+antlr4@^4.11.0:
+ version "4.13.0"
+ resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.0.tgz#25c0b17f0d9216de114303d38bafd6f181d5447f"
+ integrity sha512-zooUbt+UscjnWyOrsuY/tVFL4rwrAGwOivpQmvmUDE22hy/lUA467Rc1rcixyRwcRUIXFYBwv7+dClDSHdmmew==
-any-promise@1.3.0, any-promise@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
- integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
+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==
-anymatch@~3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
- integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
+anymatch@~3.1.1, 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"
-app-module-path@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5"
- integrity sha1-ZBqlXft9am8KgUHEucCqULbCTdU=
-
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
@@ -697,730 +1760,257 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
-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 sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=
- dependencies:
- typical "^2.6.0"
+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@^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==
+array-back@^3.0.1, array-back@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0"
+ integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==
+
+array-back@^4.0.1, array-back@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e"
+ integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==
+
+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:
- typical "^2.6.1"
+ call-bind "^1.0.2"
+ is-array-buffer "^3.0.1"
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
- integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
+ integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
-array-includes@^3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348"
- integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==
+array-includes@^3.1.6:
+ version "3.1.6"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f"
+ integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==
dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0"
- is-string "^1.0.5"
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ get-intrinsic "^1.1.3"
+ 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.flat@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
- integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==
+array-uniq@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+ integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==
+
+array.prototype.flat@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2"
+ integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==
dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-shim-unscopables "^1.0.0"
-array.prototype.map@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec"
- integrity sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==
+array.prototype.flatmap@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183"
+ integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==
dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- es-array-method-boxes-properly "^1.0.0"
- is-string "^1.0.4"
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-shim-unscopables "^1.0.0"
-arrify@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
- integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
+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==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-array-method-boxes-properly "^1.0.0"
+ is-string "^1.0.7"
-asn1.js@^4.0.0:
- version "4.10.1"
- resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
- integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==
+arraybuffer.prototype.slice@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb"
+ integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==
dependencies:
- bn.js "^4.0.0"
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
+ array-buffer-byte-length "^1.0.0"
+ call-bind "^1.0.2"
+ define-properties "^1.2.0"
+ get-intrinsic "^1.2.1"
+ is-array-buffer "^3.0.2"
+ is-shared-array-buffer "^1.0.2"
+
+arrify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+ integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==
+
+asap@~2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+ integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
asn1@~0.2.3:
- version "0.2.4"
- resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
- integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
+ version "0.2.6"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
+ integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
dependencies:
safer-buffer "~2.1.0"
+assert-diff@1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/assert-diff/-/assert-diff-1.2.6.tgz#1b44d6f24a7e3018f557768ee350ae9a732c2fc6"
+ integrity sha512-cKyCfCQrLsHubcvDo4n5lGJPxN5gwpm4Hmsjs9/DJCFs4a5jiNvhKRxKP2DZGxNxOf9Iv3pxOoBSCQ+8eiNIKA==
+ dependencies:
+ assert-plus "1.0.0"
+ json-diff "0.5.2"
+
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
- integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+ integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
assertion-error@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
-ast-parents@0.0.1:
+ast-parents@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3"
- integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM=
-
-astral-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
- integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
+ integrity sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==
-async-eventemitter@^0.2.2:
- version "0.2.4"
- resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca"
- integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==
- dependencies:
- async "^2.4.0"
+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==
async-limiter@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
-async@1.x, async@^1.4.2:
+async@1.x:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
- integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
-
-async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0:
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
- integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
- dependencies:
- lodash "^4.17.14"
+ integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
- integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
+ integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
-await-semaphore@^0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/await-semaphore/-/await-semaphore-0.1.3.tgz#2b88018cc8c28e06167ae1cdff02504f1f9688d3"
- integrity sha512-d1W2aNSYcz/sxYO4pMGX9vq65qOTu0P800epMud+6cYYX0QcT7zyqcxec3VWzpgvdXo57UWmVbZpLMjX2m1I7Q==
+at-least-node@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
+ integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
+
+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==
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
- integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
+ integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==
aws4@^1.8.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2"
- integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==
-
-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"
- integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=
- dependencies:
- chalk "^1.1.3"
- esutils "^2.0.2"
- js-tokens "^3.0.2"
-
-babel-core@^6.0.14, babel-core@^6.26.0:
- version "6.26.3"
- resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207"
- integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==
- dependencies:
- babel-code-frame "^6.26.0"
- babel-generator "^6.26.0"
- babel-helpers "^6.24.1"
- babel-messages "^6.23.0"
- babel-register "^6.26.0"
- babel-runtime "^6.26.0"
- babel-template "^6.26.0"
- babel-traverse "^6.26.0"
- babel-types "^6.26.0"
- babylon "^6.18.0"
- convert-source-map "^1.5.1"
- debug "^2.6.9"
- json5 "^0.5.1"
- lodash "^4.17.4"
- minimatch "^3.0.4"
- path-is-absolute "^1.0.1"
- private "^0.1.8"
- slash "^1.0.0"
- source-map "^0.5.7"
-
-babel-generator@^6.26.0:
- version "6.26.1"
- resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90"
- integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==
- dependencies:
- babel-messages "^6.23.0"
- babel-runtime "^6.26.0"
- babel-types "^6.26.0"
- detect-indent "^4.0.0"
- jsesc "^1.3.0"
- lodash "^4.17.4"
- source-map "^0.5.7"
- trim-right "^1.0.1"
-
-babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
- integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=
- dependencies:
- babel-helper-explode-assignable-expression "^6.24.1"
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-helper-call-delegate@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
- integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=
- dependencies:
- babel-helper-hoist-variables "^6.24.1"
- babel-runtime "^6.22.0"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
-babel-helper-define-map@^6.24.1:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f"
- integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=
- dependencies:
- babel-helper-function-name "^6.24.1"
- babel-runtime "^6.26.0"
- babel-types "^6.26.0"
- lodash "^4.17.4"
-
-babel-helper-explode-assignable-expression@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa"
- integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo=
- dependencies:
- babel-runtime "^6.22.0"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
-babel-helper-function-name@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
- integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=
- dependencies:
- babel-helper-get-function-arity "^6.24.1"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
-babel-helper-get-function-arity@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
- integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=
- dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-helper-hoist-variables@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76"
- integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY=
- dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-helper-optimise-call-expression@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
- integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=
- dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-helper-regex@^6.24.1:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72"
- integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=
- dependencies:
- babel-runtime "^6.26.0"
- babel-types "^6.26.0"
- lodash "^4.17.4"
-
-babel-helper-remap-async-to-generator@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b"
- integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=
- dependencies:
- babel-helper-function-name "^6.24.1"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
-babel-helper-replace-supers@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a"
- integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo=
- dependencies:
- babel-helper-optimise-call-expression "^6.24.1"
- babel-messages "^6.23.0"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
-babel-helpers@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
- integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=
- dependencies:
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-messages@^6.23.0:
- version "6.23.0"
- resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
- integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-check-es2015-constants@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"
- integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-syntax-async-functions@^6.8.0:
- version "6.13.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
- integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=
-
-babel-plugin-syntax-exponentiation-operator@^6.8.0:
- version "6.13.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
- integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=
-
-babel-plugin-syntax-trailing-function-commas@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
- integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=
-
-babel-plugin-transform-async-to-generator@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761"
- integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=
- dependencies:
- babel-helper-remap-async-to-generator "^6.24.1"
- babel-plugin-syntax-async-functions "^6.8.0"
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-arrow-functions@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
- integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141"
- integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-block-scoping@^6.23.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f"
- integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=
- dependencies:
- babel-runtime "^6.26.0"
- babel-template "^6.26.0"
- babel-traverse "^6.26.0"
- babel-types "^6.26.0"
- lodash "^4.17.4"
-
-babel-plugin-transform-es2015-classes@^6.23.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db"
- integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=
- dependencies:
- babel-helper-define-map "^6.24.1"
- babel-helper-function-name "^6.24.1"
- babel-helper-optimise-call-expression "^6.24.1"
- babel-helper-replace-supers "^6.24.1"
- babel-messages "^6.23.0"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
-babel-plugin-transform-es2015-computed-properties@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3"
- integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=
- dependencies:
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-plugin-transform-es2015-destructuring@^6.23.0:
- version "6.23.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d"
- integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-duplicate-keys@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e"
- integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4=
- dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-plugin-transform-es2015-for-of@^6.23.0:
- version "6.23.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691"
- integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-function-name@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b"
- integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=
- dependencies:
- babel-helper-function-name "^6.24.1"
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-plugin-transform-es2015-literals@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e"
- integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154"
- integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=
- dependencies:
- babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
- version "6.26.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3"
- integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==
- dependencies:
- babel-plugin-transform-strict-mode "^6.24.1"
- babel-runtime "^6.26.0"
- babel-template "^6.26.0"
- babel-types "^6.26.0"
-
-babel-plugin-transform-es2015-modules-systemjs@^6.23.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23"
- integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=
- dependencies:
- babel-helper-hoist-variables "^6.24.1"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-plugin-transform-es2015-modules-umd@^6.23.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468"
- integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg=
- dependencies:
- babel-plugin-transform-es2015-modules-amd "^6.24.1"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-plugin-transform-es2015-object-super@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d"
- integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40=
- dependencies:
- babel-helper-replace-supers "^6.24.1"
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-parameters@^6.23.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b"
- integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=
- dependencies:
- babel-helper-call-delegate "^6.24.1"
- babel-helper-get-function-arity "^6.24.1"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
-babel-plugin-transform-es2015-shorthand-properties@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0"
- integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=
- dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-plugin-transform-es2015-spread@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1"
- integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-sticky-regex@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc"
- integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw=
- dependencies:
- babel-helper-regex "^6.24.1"
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-plugin-transform-es2015-template-literals@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d"
- integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-typeof-symbol@^6.23.0:
- version "6.23.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372"
- integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=
- dependencies:
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-es2015-unicode-regex@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9"
- integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek=
- dependencies:
- babel-helper-regex "^6.24.1"
- babel-runtime "^6.22.0"
- regexpu-core "^2.0.0"
-
-babel-plugin-transform-exponentiation-operator@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
- integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=
- dependencies:
- babel-helper-builder-binary-assignment-operator-visitor "^6.24.1"
- babel-plugin-syntax-exponentiation-operator "^6.8.0"
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-regenerator@^6.22.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
- integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=
- dependencies:
- regenerator-transform "^0.10.0"
-
-babel-plugin-transform-strict-mode@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"
- integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=
- dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
-
-babel-preset-env@^1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a"
- integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==
- dependencies:
- babel-plugin-check-es2015-constants "^6.22.0"
- babel-plugin-syntax-trailing-function-commas "^6.22.0"
- babel-plugin-transform-async-to-generator "^6.22.0"
- babel-plugin-transform-es2015-arrow-functions "^6.22.0"
- babel-plugin-transform-es2015-block-scoped-functions "^6.22.0"
- babel-plugin-transform-es2015-block-scoping "^6.23.0"
- babel-plugin-transform-es2015-classes "^6.23.0"
- babel-plugin-transform-es2015-computed-properties "^6.22.0"
- babel-plugin-transform-es2015-destructuring "^6.23.0"
- babel-plugin-transform-es2015-duplicate-keys "^6.22.0"
- babel-plugin-transform-es2015-for-of "^6.23.0"
- babel-plugin-transform-es2015-function-name "^6.22.0"
- babel-plugin-transform-es2015-literals "^6.22.0"
- babel-plugin-transform-es2015-modules-amd "^6.22.0"
- babel-plugin-transform-es2015-modules-commonjs "^6.23.0"
- babel-plugin-transform-es2015-modules-systemjs "^6.23.0"
- babel-plugin-transform-es2015-modules-umd "^6.23.0"
- babel-plugin-transform-es2015-object-super "^6.22.0"
- babel-plugin-transform-es2015-parameters "^6.23.0"
- babel-plugin-transform-es2015-shorthand-properties "^6.22.0"
- babel-plugin-transform-es2015-spread "^6.22.0"
- babel-plugin-transform-es2015-sticky-regex "^6.22.0"
- babel-plugin-transform-es2015-template-literals "^6.22.0"
- babel-plugin-transform-es2015-typeof-symbol "^6.23.0"
- babel-plugin-transform-es2015-unicode-regex "^6.22.0"
- babel-plugin-transform-exponentiation-operator "^6.22.0"
- babel-plugin-transform-regenerator "^6.22.0"
- browserslist "^3.2.6"
- invariant "^2.2.2"
- semver "^5.3.0"
-
-babel-register@^6.26.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
- integrity sha1-btAhFz4vy0htestFxgCahW9kcHE=
- dependencies:
- babel-core "^6.26.0"
- babel-runtime "^6.26.0"
- core-js "^2.5.0"
- home-or-tmp "^2.0.0"
- lodash "^4.17.4"
- mkdirp "^0.5.1"
- source-map-support "^0.4.15"
-
-babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
- integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
- dependencies:
- core-js "^2.4.0"
- regenerator-runtime "^0.11.0"
-
-babel-template@^6.24.1, babel-template@^6.26.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
- integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=
- dependencies:
- babel-runtime "^6.26.0"
- babel-traverse "^6.26.0"
- babel-types "^6.26.0"
- babylon "^6.18.0"
- lodash "^4.17.4"
-
-babel-traverse@^6.24.1, babel-traverse@^6.26.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
- integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=
- dependencies:
- babel-code-frame "^6.26.0"
- babel-messages "^6.23.0"
- babel-runtime "^6.26.0"
- babel-types "^6.26.0"
- babylon "^6.18.0"
- debug "^2.6.8"
- globals "^9.18.0"
- invariant "^2.2.2"
- lodash "^4.17.4"
-
-babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
- integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=
- dependencies:
- babel-runtime "^6.26.0"
- esutils "^2.0.2"
- lodash "^4.17.4"
- to-fast-properties "^1.0.3"
-
-babelify@^7.3.0:
- version "7.3.0"
- resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5"
- integrity sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=
- dependencies:
- babel-core "^6.0.14"
- object-assign "^4.0.0"
-
-babylon@^6.18.0:
- version "6.18.0"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
- integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
-
-backoff@^2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f"
- integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=
- dependencies:
- precond "0.2"
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3"
+ integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==
balanced-match@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
- integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
+ 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, base-x@^3.0.8:
- version "3.0.8"
- resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d"
- integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==
+ 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.0.2, base64-js@^1.3.0:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
- integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
+base-x@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a"
+ integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==
+
+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.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
- integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
+ integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
dependencies:
tweetnacl "^0.14.3"
-bignumber.js@^9.0.0:
- version "9.0.0"
- resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075"
- integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==
+bech32@1.1.4, bech32@^1.1.3:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
+ integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
-binary-extensions@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9"
- integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==
+big-integer@1.6.36:
+ version "1.6.36"
+ resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36"
+ integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==
-bindings@^1.2.1, bindings@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
- integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
- dependencies:
- file-uri-to-path "1.0.0"
+big.js@^6.0.3:
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f"
+ integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==
-bip66@^1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22"
- integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=
- dependencies:
- safe-buffer "^5.0.1"
+bigint-crypto-utils@^3.0.23:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77"
+ integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==
-bl@^1.0.0:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
- integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==
+bignumber.js@*, 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==
+
+bignumber.js@^7.2.1:
+ version "7.2.1"
+ resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f"
+ integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==
+
+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@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-5.1.0.tgz#183715f678c7188ecef9fe475d90209400624273"
+ integrity sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==
dependencies:
- readable-stream "^2.3.5"
- safe-buffer "^5.1.1"
+ buffer "^6.0.3"
+ inherits "^2.0.4"
+ readable-stream "^3.4.0"
blakejs@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5"
- integrity sha1-ad+S75U6qIylGjLfarHFShVfx6U=
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814"
+ integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==
-bluebird@^3.5.0:
+bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
@@ -1428,38 +2018,58 @@ bluebird@^3.5.0:
bn.js@4.11.6:
version "4.11.6"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
- integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU=
-
-bn.js@4.11.8:
- version "4.11.8"
- resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
- integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
+ integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0:
- version "4.11.9"
- resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
- integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
+bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9:
+ version "4.12.0"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
+ integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
-bn.js@^5.1.1, bn.js@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0"
- integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==
+bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
+ integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
-body-parser@1.19.0, body-parser@^1.16.0:
- version "1.19.0"
- resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
- integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
+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==
dependencies:
- bytes "3.1.0"
+ bytes "3.1.2"
content-type "~1.0.4"
debug "2.6.9"
- depd "~1.1.2"
- http-errors "1.7.2"
+ 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.1"
+ 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.3.0"
- qs "6.7.0"
- raw-body "2.4.0"
- type-is "~1.6.17"
+ on-finished "2.4.1"
+ qs "6.11.0"
+ raw-body "2.5.2"
+ type-is "~1.6.18"
+ unpipe "1.0.0"
+
+boolbase@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+ integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
brace-expansion@^1.1.7:
version "1.1.11"
@@ -1469,24 +2079,41 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
-braces@^3.0.1, braces@~3.0.2:
+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.0.1:
+brorand@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
- integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
+ 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.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6, browserify-aes@^1.2.0:
+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==
@@ -1498,60 +2125,17 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6, browserify-
inherits "^2.0.1"
safe-buffer "^5.0.1"
-browserify-cipher@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
- integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
- dependencies:
- browserify-aes "^1.0.4"
- browserify-des "^1.0.0"
- evp_bytestokey "^1.0.0"
-
-browserify-des@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
- integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
- dependencies:
- cipher-base "^1.0.1"
- des.js "^1.0.0"
- inherits "^2.0.1"
- safe-buffer "^5.1.2"
-
-browserify-rsa@^4.0.0, browserify-rsa@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
- integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=
- dependencies:
- bn.js "^4.1.0"
- randombytes "^2.0.1"
-
-browserify-sign@^4.0.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.0.tgz#545d0b1b07e6b2c99211082bf1b12cce7a0b0e11"
- integrity sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==
- dependencies:
- bn.js "^5.1.1"
- browserify-rsa "^4.0.1"
- create-hash "^1.2.0"
- create-hmac "^1.1.7"
- elliptic "^6.5.2"
- inherits "^2.0.4"
- parse-asn1 "^5.1.5"
- readable-stream "^3.6.0"
- safe-buffer "^5.2.0"
-
-browserslist@^3.2.6:
- version "3.2.8"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6"
- integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==
+bs58@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279"
+ integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==
dependencies:
- caniuse-lite "^1.0.30000844"
- electron-to-chromium "^1.3.47"
+ base-x "^4.0.0"
-bs58@^4.0.0:
+bs58@^4.0.0, bs58@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
- integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo=
+ integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==
dependencies:
base-x "^3.0.2"
@@ -1564,143 +2148,173 @@ bs58check@^2.1.2:
create-hash "^1.1.0"
safe-buffer "^5.1.2"
-btoa@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
- integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
-
-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-crc32@~0.2.3:
- version "0.2.13"
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
-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 sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
-
-buffer-fill@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
- integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
-
buffer-from@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
- integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
+ 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-to-arraybuffer@^0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a"
- integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=
+ integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==
buffer-xor@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
- integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
+ integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==
-buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0:
- version "5.6.0"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
- integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==
+buffer@6.0.3, 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.0.2"
- ieee754 "^1.1.4"
+ base64-js "^1.3.1"
+ ieee754 "^1.2.1"
-bytes@3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
- integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
+buffer@^5.0.5, buffer@^5.5.0, buffer@^5.6.0:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
+ integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
+ dependencies:
+ base64-js "^1.3.1"
+ ieee754 "^1.1.13"
+
+bufferutil@^4.0.1:
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad"
+ integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==
+ dependencies:
+ node-gyp-build "^4.3.0"
+
+bytes@3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
+ integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
+
+cacheable-lookup@^5.0.3:
+ version "5.0.4"
+ resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
+ integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
-cacheable-request@^6.0.0:
+cacheable-lookup@^6.0.4:
version "6.1.0"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
- integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
+ resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385"
+ integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==
+
+cacheable-request@^7.0.2:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817"
+ integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==
dependencies:
clone-response "^1.0.2"
get-stream "^5.1.0"
http-cache-semantics "^4.0.0"
- keyv "^3.0.0"
+ keyv "^4.0.0"
lowercase-keys "^2.0.0"
- normalize-url "^4.1.0"
- responselike "^1.0.2"
-
-caller-callsite@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
- integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
- dependencies:
- callsites "^2.0.0"
+ normalize-url "^6.0.1"
+ responselike "^2.0.0"
-caller-path@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4"
- integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
+call-bind@^1.0.0, 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:
- caller-callsite "^2.0.0"
-
-callsites@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
- integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
+ function-bind "^1.1.1"
+ get-intrinsic "^1.0.2"
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@^5.0.0:
+camel-case@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
+ integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==
+ dependencies:
+ no-case "^2.2.0"
+ upper-case "^1.1.1"
+
+camelcase-keys@^6.2.2:
+ version "6.2.2"
+ resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0"
+ integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==
+ dependencies:
+ camelcase "^5.3.1"
+ map-obj "^4.0.0"
+ quick-lru "^4.0.1"
+
+camelcase@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
+ integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==
+
+camelcase@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
+ integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==
+
+camelcase@^5.0.0, camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-caniuse-lite@^1.0.30000844:
- version "1.0.30001104"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001104.tgz#4e3d5b3b1dd3c3529f10cb7f519c62ba3e579f5d"
- integrity sha512-pkpCg7dmI/a7WcqM2yfdOiT4Xx5tzyoHAXWsX5/HxZ3TemwDZs0QXdqbE0UPLPVy/7BeK7693YfzfRYfu1YVpg==
+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==
-caseless@~0.12.0:
+caseless@^0.12.0, caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
- integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
+ integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
-chai@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
- integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==
+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@9.0.2:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/cbor/-/cbor-9.0.2.tgz#536b4f2d544411e70ec2b19a2453f10f83cd9fdb"
+ integrity sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==
+ dependencies:
+ nofilter "^3.1.0"
+
+cbor@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c"
+ integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==
+ dependencies:
+ bignumber.js "^9.0.1"
+ nofilter "^1.0.4"
+
+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.7, chai@^4.2.0:
+ 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 "^3.0.1"
+ deep-eql "^4.1.2"
get-func-name "^2.0.0"
- pathval "^1.1.0"
+ loupe "^2.3.1"
+ pathval "^1.1.1"
type-detect "^4.0.5"
-chalk@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
- integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
- dependencies:
- ansi-styles "^2.2.1"
- escape-string-regexp "^1.0.2"
- has-ansi "^2.0.0"
- strip-ansi "^3.0.0"
- supports-color "^2.0.0"
-
-chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2:
+chalk@^2.0.0, chalk@^2.3.2, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -1709,51 +2323,113 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
-chalk@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
- integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
+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"
-chardet@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
- integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
+change-case@3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.2.tgz#fd48746cce02f03f0a672577d1d3a8dc2eceb037"
+ integrity sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==
+ dependencies:
+ camel-case "^3.0.0"
+ constant-case "^2.0.0"
+ dot-case "^2.1.0"
+ header-case "^1.0.0"
+ is-lower-case "^1.1.0"
+ is-upper-case "^1.1.0"
+ lower-case "^1.1.1"
+ lower-case-first "^1.0.0"
+ no-case "^2.3.2"
+ param-case "^2.1.0"
+ pascal-case "^2.0.0"
+ path-case "^2.1.0"
+ sentence-case "^2.1.0"
+ snake-case "^2.1.0"
+ swap-case "^1.1.0"
+ title-case "^2.1.0"
+ upper-case "^1.1.1"
+ upper-case-first "^1.1.0"
+
+charenc@0.0.2, "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 sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
+ integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
-checkpoint-store@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06"
- integrity sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=
+cheerio-select@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4"
+ integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==
+ dependencies:
+ boolbase "^1.0.0"
+ css-select "^5.1.0"
+ css-what "^6.1.0"
+ domelementtype "^2.3.0"
+ domhandler "^5.0.3"
+ domutils "^3.0.1"
+
+cheerio@^1.0.0-rc.2:
+ version "1.0.0-rc.12"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683"
+ integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==
+ dependencies:
+ cheerio-select "^2.1.0"
+ dom-serializer "^2.0.0"
+ domhandler "^5.0.3"
+ domutils "^3.0.1"
+ htmlparser2 "^8.0.1"
+ parse5 "^7.0.0"
+ parse5-htmlparser2-tree-adapter "^7.0.0"
+
+chokidar@3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6"
+ integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==
dependencies:
- functional-red-black-tree "^1.0.1"
+ 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.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450"
- integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==
+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.1"
+ anymatch "~3.1.2"
braces "~3.0.2"
- glob-parent "~5.1.0"
+ glob-parent "~5.1.2"
is-binary-path "~2.1.0"
is-glob "~4.0.1"
normalize-path "~3.0.0"
- readdirp "~3.3.0"
+ readdirp "~3.6.0"
optionalDependencies:
- fsevents "~2.1.2"
+ fsevents "~2.3.2"
-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==
+ci-info@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
+ integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
+
cids@^0.7.1:
version "0.7.5"
resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2"
@@ -1765,6 +2441,16 @@ cids@^0.7.1:
multicodec "^1.0.0"
multihashes "~0.4.15"
+cids@^1.0.0, cids@^1.1.5, cids@^1.1.6:
+ version "1.1.9"
+ resolved "https://registry.yarnpkg.com/cids/-/cids-1.1.9.tgz#402c26db5c07059377bcd6fb82f2a24e7f2f4a4f"
+ integrity sha512-l11hWRfugIcbGuTZwAM5PwpjPPjyb6UZOGwlHSnOBV5o07XhQ4gNpBN67FbODvpjyHtd+0Xs6KNvUcGBiDRsdg==
+ dependencies:
+ multibase "^4.0.1"
+ multicodec "^3.0.1"
+ multihashes "^4.0.1"
+ uint8arrays "^3.0.0"
+
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"
@@ -1778,17 +2464,56 @@ class-is@^1.1.0:
resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825"
integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==
-cli-cursor@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
- integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
+classic-level@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8"
+ integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==
dependencies:
- restore-cursor "^2.0.0"
+ abstract-level "^1.0.2"
+ catering "^2.1.0"
+ module-error "^1.0.1"
+ napi-macros "^2.2.2"
+ node-gyp-build "^4.3.0"
-cli-width@^2.0.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48"
- integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==
+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==
+
+cli-color@~0.1.6:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-0.1.7.tgz#adc3200fa471cc211b0da7f566b71e98b9d67347"
+ integrity sha512-xNaQxWYgI6DD4xIJLn8GY2zDZVbrN0vsU1fEbDNAHZRyceWhpj7A08mYcG1AY92q1Aw0geYkVfiAcEYIZtuTSg==
+ dependencies:
+ es5-ext "0.8.x"
+
+cli-table3@^0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202"
+ integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==
+ dependencies:
+ object-assign "^4.1.0"
+ string-width "^2.1.1"
+ optionalDependencies:
+ colors "^1.1.2"
+
+cli-table3@^0.6.0:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2"
+ integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==
+ dependencies:
+ string-width "^4.2.0"
+ optionalDependencies:
+ "@colors/colors" "1.5.0"
+
+cliui@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
+ integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+ wrap-ansi "^2.0.0"
cliui@^5.0.0:
version "5.0.0"
@@ -1799,17 +2524,26 @@ cliui@^5.0.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"
+ integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.0"
+ wrap-ansi "^7.0.0"
+
clone-response@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
- integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3"
+ integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==
dependencies:
mimic-response "^1.0.0"
-clone@^2.0.0, clone@^2.1.1:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
- integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
+code-point-at@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+ integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
color-convert@^1.9.0:
version "1.9.3"
@@ -1828,13 +2562,18 @@ color-convert@^2.0.1:
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
- integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
+ 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==
+colors@1.4.0, colors@^1.1.2:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
+ integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
+
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -1847,38 +2586,42 @@ command-exists@^1.2.8:
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==
+command-line-args@^5.1.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e"
+ integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==
dependencies:
- array-back "^2.0.0"
- find-replace "^1.0.3"
- typical "^2.6.1"
+ array-back "^3.1.0"
+ find-replace "^3.0.0"
+ lodash.camelcase "^4.3.0"
+ typical "^4.0.0"
-commander@2.18.0:
- version "2.18.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970"
- integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==
+command-line-usage@^6.1.0:
+ version "6.1.3"
+ resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957"
+ integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==
+ dependencies:
+ array-back "^4.0.2"
+ chalk "^2.4.2"
+ table-layout "^1.0.2"
+ typical "^5.2.0"
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@~2.8.1:
- version "2.8.1"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4"
- integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=
- dependencies:
- graceful-readlink ">= 1.0.0"
+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==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
- integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+ integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
-concat-stream@^1.5.1:
+concat-stream@^1.6.0, 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==
@@ -1888,17 +2631,20 @@ concat-stream@^1.5.1:
readable-stream "^2.2.2"
typedarray "^0.0.6"
-contains-path@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
- integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=
+constant-case@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46"
+ integrity sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==
+ dependencies:
+ snake-case "^2.1.0"
+ upper-case "^1.1.1"
-content-disposition@0.5.3:
- version "0.5.3"
- resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
- integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
+content-disposition@0.5.4:
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
+ integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
dependencies:
- safe-buffer "5.1.2"
+ safe-buffer "5.2.1"
content-hash@^2.5.2:
version "2.5.2"
@@ -1909,42 +2655,35 @@ 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==
-
-convert-source-map@^1.5.1:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
- integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
- dependencies:
- safe-buffer "~5.1.1"
+content-type@~1.0.4, content-type@~1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
+ integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
- integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
-
-cookie@0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
- integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
+ integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
-cookiejar@^2.1.1:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
- integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
+cookie@0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
+ integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
-core-js@^2.4.0, core-js@^2.5.0:
- version "2.6.11"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
- integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
+cookie@^0.4.1:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
+ integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
-core-util-is@1.0.2, core-util-is@~1.0.0:
+core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
+ integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
+
+core-util-is@~1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
cors@^2.8.1:
version "2.8.5"
@@ -1954,23 +2693,20 @@ cors@^2.8.1:
object-assign "^4"
vary "^1"
-cosmiconfig@^5.0.7:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
- integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
+cosmiconfig@^8.0.0:
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd"
+ integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==
dependencies:
- import-fresh "^2.0.0"
- is-directory "^0.3.1"
- js-yaml "^3.13.1"
- parse-json "^4.0.0"
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.0"
+ parse-json "^5.0.0"
+ path-type "^4.0.0"
-create-ecdh@^4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
- integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==
- dependencies:
- bn.js "^4.1.0"
- elliptic "^6.0.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"
@@ -1983,7 +2719,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
ripemd160 "^2.0.1"
sha.js "^2.4.0"
-create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
+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==
@@ -1995,26 +2731,19 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-cross-fetch@^2.1.0, cross-fetch@^2.1.1:
- version "2.2.3"
- resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e"
- integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==
- dependencies:
- node-fetch "2.1.2"
- whatwg-fetch "2.0.4"
+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@^6.0.0, cross-spawn@^6.0.5:
- version "6.0.5"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
- integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
+cross-fetch@^3.1.4:
+ version "3.1.8"
+ resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82"
+ integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
dependencies:
- nice-try "^1.0.4"
- path-key "^2.0.1"
- semver "^5.5.0"
- shebang-command "^1.2.0"
- which "^1.2.9"
+ node-fetch "^2.6.12"
-cross-spawn@^7.0.2:
+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==
@@ -2023,22 +2752,39 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
-crypto-browserify@3.12.0:
- version "3.12.0"
- resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
- integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
+crypt@0.0.2, "crypt@>= 0.0.1":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
+ integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
+
+crypto-addr-codec@^0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz#e16cea892730178fe25a38f6d15b680cab3124ae"
+ integrity sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==
dependencies:
- browserify-cipher "^1.0.0"
- browserify-sign "^4.0.0"
- create-ecdh "^4.0.0"
- create-hash "^1.1.0"
- create-hmac "^1.1.0"
- diffie-hellman "^5.0.0"
- inherits "^2.0.1"
- pbkdf2 "^3.0.3"
- public-encrypt "^4.0.0"
- randombytes "^2.0.0"
- randomfill "^1.0.3"
+ base-x "^3.0.8"
+ big-integer "1.6.36"
+ blakejs "^1.1.0"
+ bs58 "^4.0.1"
+ ripemd160-min "0.0.6"
+ safe-buffer "^5.2.0"
+ sha3 "^2.1.1"
+
+css-select@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
+ integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
+ dependencies:
+ boolbase "^1.0.0"
+ css-what "^6.1.0"
+ domhandler "^5.0.2"
+ domutils "^3.0.1"
+ nth-check "^2.0.1"
+
+css-what@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
+ integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
d@1, d@^1.0.1:
version "1.0.1"
@@ -2051,16 +2797,16 @@ d@1, d@^1.0.1:
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
- integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
+ integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==
dependencies:
assert-plus "^1.0.0"
death@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318"
- integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=
+ integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==
-debug@2.6.9, debug@^2.2.0, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9:
+debug@2.6.9, debug@^2.2.0:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -2074,182 +2820,133 @@ debug@3.2.6:
dependencies:
ms "^2.1.1"
-debug@4, debug@^4.0.1, debug@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
- integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
+debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, 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@^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.2.0:
+decamelize-keys@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8"
+ integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==
+ dependencies:
+ decamelize "^1.1.0"
+ map-obj "^1.0.0"
+
+decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
- integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+ integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
+
+decamelize@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
+ integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
decode-uri-component@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
- integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
+ integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
-decompress-response@^3.2.0, decompress-response@^3.3.0:
+decompress-response@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
+ integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==
dependencies:
mimic-response "^1.0.0"
-decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1"
- integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==
- dependencies:
- file-type "^5.2.0"
- is-stream "^1.1.0"
- tar-stream "^1.5.2"
-
-decompress-tarbz2@^4.0.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b"
- integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==
- dependencies:
- decompress-tar "^4.1.0"
- file-type "^6.1.0"
- is-stream "^1.1.0"
- seek-bzip "^1.0.5"
- unbzip2-stream "^1.0.9"
-
-decompress-targz@^4.0.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee"
- integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==
+decompress-response@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
+ integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
dependencies:
- decompress-tar "^4.1.1"
- file-type "^5.2.0"
- is-stream "^1.1.0"
+ mimic-response "^3.1.0"
-decompress-unzip@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69"
- integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k=
- dependencies:
- file-type "^3.8.0"
- get-stream "^2.2.0"
- pify "^2.3.0"
- yauzl "^2.4.2"
-
-decompress@^4.0.0:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118"
- integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==
- dependencies:
- decompress-tar "^4.0.0"
- decompress-tarbz2 "^4.0.0"
- decompress-targz "^4.0.0"
- decompress-unzip "^4.0.1"
- graceful-fs "^4.1.10"
- make-dir "^1.0.0"
- pify "^2.3.0"
- strip-dirs "^2.0.0"
-
-deep-eql@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
- integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==
+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-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==
- dependencies:
- is-arguments "^1.0.4"
- is-date-object "^1.0.1"
- is-regex "^1.0.4"
- object-is "^1.0.1"
- object-keys "^1.1.1"
- regexp.prototype.flags "^1.2.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, deep-is@~0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
- integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
-
-defer-to-connect@^1.0.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
- integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
+ 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==
-deferred-leveldown@~1.2.1:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb"
- integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==
- dependencies:
- abstract-leveldown "~2.6.0"
+defer-to-connect@^2.0.0, defer-to-connect@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
+ integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
-define-properties@^1.1.2, define-properties@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
- integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
+define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, 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:
- object-keys "^1.0.12"
-
-defined@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
- integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
+ 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 sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+ integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
-depd@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
- integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
+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==
-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==
- dependencies:
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
+destroy@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
+ integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
-destroy@~1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
- integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
+detect-indent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
+ integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==
-detect-indent@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
- integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg=
- dependencies:
- repeating "^2.0.0"
+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==
-detect-port@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1"
- integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==
- dependencies:
- address "^1.0.1"
- debug "^2.6.0"
+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.2, diff@^4.0.1, diff@^4.0.2:
+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==
-diffie-hellman@^5.0.0:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
- integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
+diff@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a"
+ integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==
+
+difflib@^0.2.4, difflib@~0.2.1:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e"
+ integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==
dependencies:
- bn.js "^4.1.0"
- miller-rabin "^4.0.0"
- randombytes "^2.0.0"
+ heap ">= 0.2.0"
dir-glob@^3.0.1:
version "3.0.1"
@@ -2263,13 +2960,12 @@ dir-to-object@^2.0.0:
resolved "https://registry.yarnpkg.com/dir-to-object/-/dir-to-object-2.0.0.tgz#29723e9bd1c3e58e4f307bd04ff634c0370c8f8a"
integrity sha512-sXs0JKIhymON7T1UZuO2Ud6VTNAx/VTBXIl4+3mjb2RgfOpt+hectX0x04YqPOPdkeOAKoJuKqwqnXXURNPNEA==
-doctrine@1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
- integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=
+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"
- isarray "^1.0.0"
doctrine@^3.0.0:
version "3.0.0"
@@ -2278,92 +2974,100 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
+dom-serializer@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
+ integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
+ dependencies:
+ domelementtype "^2.3.0"
+ domhandler "^5.0.2"
+ entities "^4.2.0"
+
dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
-dotignore@~0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905"
- integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==
+domelementtype@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
+ integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
+
+domhandler@^5.0.2, domhandler@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
+ integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
- minimatch "^3.0.4"
+ domelementtype "^2.3.0"
-drbg.js@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b"
- integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=
+domutils@^3.0.1:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
+ integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
- browserify-aes "^1.0.6"
- create-hash "^1.1.2"
- create-hmac "^1.1.4"
+ dom-serializer "^2.0.0"
+ domelementtype "^2.3.0"
+ domhandler "^5.0.3"
-duplexer3@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
+dot-case@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee"
+ integrity sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==
+ dependencies:
+ no-case "^2.2.0"
+
+dotenv-cli@7.3.0:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-7.3.0.tgz#21e33e7944713001677658d68856063968edfbd2"
+ integrity sha512-314CA4TyK34YEJ6ntBf80eUY+t1XaFLyem1k9P0sX1gn30qThZ5qZr/ZwE318gEnzyYP9yj9HJk6SqwE0upkfw==
+ dependencies:
+ cross-spawn "^7.0.3"
+ dotenv "^16.3.0"
+ dotenv-expand "^10.0.0"
+ minimist "^1.2.6"
+
+dotenv-expand@^10.0.0:
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37"
+ integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==
+
+dotenv@16.4.1, dotenv@^16.3.0:
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11"
+ integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==
+
+dreamopt@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/dreamopt/-/dreamopt-0.6.0.tgz#d813ccdac8d39d8ad526775514a13dda664d6b4b"
+ integrity sha512-KRJa47iBEK0y6ZtgCgy2ykuvMT8c9gj3ua9Dv7vCkclFJJeH2FjhGY2xO5qBoWGahsjCGMlk4Cq9wJYeWxuYhQ==
+ dependencies:
+ wordwrap ">=0.0.2"
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
- integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
+ integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
-ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11:
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
- integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
- dependencies:
- safe-buffer "^5.0.1"
-
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
- integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
-
-electron-to-chromium@^1.3.47:
- version "1.3.502"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.502.tgz#6a55e993ef60a01fbdc2152ef5e47ee00c885c98"
- integrity sha512-TIeXOaHAvfP7FemGUtAJxStmOc1YFGWFNqdey/4Nk41L9b1nMmDVDGNMIWhZJvOfJxix6Cv5FGEnBK+yvw3UTg==
-
-elliptic@6.3.3:
- version "6.3.3"
- resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f"
- integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8=
- dependencies:
- bn.js "^4.4.0"
- brorand "^1.0.1"
- hash.js "^1.0.0"
- inherits "^2.0.1"
-
-elliptic@6.5.2:
- version "6.5.2"
- resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762"
- integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==
- dependencies:
- bn.js "^4.4.0"
- brorand "^1.0.1"
- hash.js "^1.0.0"
- hmac-drbg "^1.0.0"
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
- minimalistic-crypto-utils "^1.0.0"
+ integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
-elliptic@6.5.3, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.5.2:
- version "6.5.3"
- resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
- integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
+elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4:
+ version "6.5.4"
+ resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
+ integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
dependencies:
- bn.js "^4.4.0"
- brorand "^1.0.1"
+ bn.js "^4.11.9"
+ brorand "^1.1.0"
hash.js "^1.0.0"
- hmac-drbg "^1.0.0"
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
- minimalistic-crypto-utils "^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@^7.0.1:
version "7.0.3"
@@ -2376,29 +3080,30 @@ emoji-regex@^8.0.0:
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
emoji-regex@^9.0.0:
- version "9.0.0"
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.0.0.tgz#48a2309cc8a1d2e9d23bc6a67c39b63032e76ea4"
- integrity sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
+ integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
- integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-
-encoding@^0.1.11:
- version "0.1.13"
- resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
- integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
- dependencies:
- iconv-lite "^0.6.2"
+ integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
-end-of-stream@^1.0.0, end-of-stream@^1.1.0:
+end-of-stream@^1.1.0:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
dependencies:
once "^1.4.0"
+enquirer@^2.3.0:
+ 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"
+
enquirer@^2.3.5:
version "2.3.6"
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
@@ -2406,12 +3111,20 @@ enquirer@^2.3.5:
dependencies:
ansi-colors "^4.1.1"
-errno@~0.1.1:
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
- integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
- dependencies:
- prr "~1.0.1"
+entities@^4.2.0, entities@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
+ integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+
+env-paths@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
+ integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
+
+err-code@^3.0.0, err-code@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920"
+ integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==
error-ex@^1.2.0, error-ex@^1.3.1:
version "1.3.2"
@@ -2420,40 +3133,71 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5:
- version "1.17.6"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a"
- integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==
+es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2:
+ version "1.22.1"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc"
+ integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==
dependencies:
+ array-buffer-byte-length "^1.0.0"
+ arraybuffer.prototype.slice "^1.0.1"
+ 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.2.1"
+ get-symbol-description "^1.0.0"
+ globalthis "^1.0.3"
+ gopd "^1.0.1"
has "^1.0.3"
- has-symbols "^1.0.1"
- is-callable "^1.2.0"
- is-regex "^1.1.0"
- object-inspect "^1.7.0"
+ 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.0"
- string.prototype.trimend "^1.0.1"
- string.prototype.trimstart "^1.0.1"
+ object.assign "^4.1.4"
+ regexp.prototype.flags "^1.5.0"
+ safe-array-concat "^1.0.0"
+ 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-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.10"
es-array-method-boxes-properly@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
-es-get-iterator@^1.0.2:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"
- integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==
+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==
dependencies:
- es-abstract "^1.17.4"
- has-symbols "^1.0.1"
- is-arguments "^1.0.4"
- is-map "^2.0.1"
- is-set "^2.0.1"
- is-string "^1.0.5"
- isarray "^2.0.5"
+ get-intrinsic "^1.1.3"
+ has "^1.0.3"
+ has-tostringtag "^1.0.0"
+
+es-shim-unscopables@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241"
+ integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==
+ dependencies:
+ has "^1.0.3"
es-to-primitive@^1.2.1:
version "1.2.1"
@@ -2464,25 +3208,35 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
+es5-ext@0.8.x:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.8.2.tgz#aba8d9e1943a895ac96837a62a39b3f55ecd94ab"
+ integrity sha512-H19ompyhnKiBdjHR1DPHvf5RHgHPmJaY9JNzFGbMbPgdsUkvnUCN1Ke8J4Y0IMyTwFM2M9l4h2GoHwzwpSmXbA==
+
es5-ext@^0.10.35, es5-ext@^0.10.50:
- version "0.10.53"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
- integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
+ version "0.10.62"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
+ integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
- es6-iterator "~2.0.3"
- es6-symbol "~3.1.3"
- next-tick "~1.0.0"
+ es6-iterator "^2.0.3"
+ es6-symbol "^3.1.3"
+ next-tick "^1.1.0"
-es6-iterator@~2.0.3:
+es6-iterator@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
- integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
+ integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==
dependencies:
d "1"
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
-es6-symbol@^3.1.1, es6-symbol@~3.1.3:
+es6-promise@^4.2.8:
+ version "4.2.8"
+ resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
+ integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
+
+es6-symbol@^3.1.1, es6-symbol@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
@@ -2490,17 +3244,22 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3:
d "^1.0.1"
ext "^1.1.2"
+escalade@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
+ integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
+
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
- integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
+ integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
-escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+escape-string-regexp@1.0.5, 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 sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+ integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
-escape-string-regexp@^4.0.0:
+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==
@@ -2508,7 +3267,7 @@ escape-string-regexp@^4.0.0:
escodegen@1.8.x:
version "1.8.1"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018"
- integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=
+ integrity sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==
dependencies:
esprima "^2.7.1"
estraverse "^1.9.1"
@@ -2517,33 +3276,33 @@ escodegen@1.8.x:
optionalDependencies:
source-map "~0.2.0"
-eslint-config-prettier@^6.11.0:
- version "6.11.0"
- resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1"
- integrity sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==
+eslint-config-prettier@6.15.0:
+ version "6.15.0"
+ resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9"
+ integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==
dependencies:
get-stdin "^6.0.0"
-eslint-config-standard@^14.1.1:
+eslint-config-standard@14.1.1:
version "14.1.1"
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea"
integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==
-eslint-import-resolver-node@^0.3.3:
- version "0.3.4"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717"
- integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==
+eslint-import-resolver-node@^0.3.7:
+ version "0.3.7"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7"
+ integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==
dependencies:
- debug "^2.6.9"
- resolve "^1.13.1"
+ debug "^3.2.7"
+ is-core-module "^2.11.0"
+ resolve "^1.22.1"
-eslint-module-utils@^2.6.0:
- version "2.6.0"
- resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6"
- integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==
+eslint-module-utils@^2.7.4:
+ 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 "^2.6.9"
- pkg-dir "^2.0.0"
+ debug "^3.2.7"
eslint-plugin-es@^3.0.0:
version "3.0.1"
@@ -2553,26 +3312,28 @@ eslint-plugin-es@^3.0.0:
eslint-utils "^2.0.0"
regexpp "^3.0.0"
-eslint-plugin-import@^2.22.0:
- version "2.22.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e"
- integrity sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==
- dependencies:
- array-includes "^3.1.1"
- array.prototype.flat "^1.2.3"
- contains-path "^0.1.0"
- debug "^2.6.9"
- doctrine "1.5.0"
- eslint-import-resolver-node "^0.3.3"
- eslint-module-utils "^2.6.0"
+eslint-plugin-import@2.27.5:
+ version "2.27.5"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65"
+ integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==
+ dependencies:
+ array-includes "^3.1.6"
+ array.prototype.flat "^1.3.1"
+ array.prototype.flatmap "^1.3.1"
+ debug "^3.2.7"
+ doctrine "^2.1.0"
+ eslint-import-resolver-node "^0.3.7"
+ eslint-module-utils "^2.7.4"
has "^1.0.3"
- minimatch "^3.0.4"
- object.values "^1.1.1"
- read-pkg-up "^2.0.0"
- resolve "^1.17.0"
- tsconfig-paths "^3.9.0"
+ is-core-module "^2.11.0"
+ is-glob "^4.0.3"
+ minimatch "^3.1.2"
+ object.values "^1.1.6"
+ resolve "^1.22.1"
+ semver "^6.3.0"
+ tsconfig-paths "^3.14.1"
-eslint-plugin-node@^11.1.0:
+eslint-plugin-node@11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d"
integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==
@@ -2584,46 +3345,31 @@ eslint-plugin-node@^11.1.0:
resolve "^1.10.1"
semver "^6.1.0"
-eslint-plugin-prettier@^3.1.4:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz#168ab43154e2ea57db992a2cd097c828171f75c2"
- integrity sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==
+eslint-plugin-prettier@3.4.1:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5"
+ integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==
dependencies:
prettier-linter-helpers "^1.0.0"
-eslint-plugin-promise@^4.2.1:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a"
- integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
+eslint-plugin-promise@4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz#61485df2a359e03149fdafc0a68b0e030ad2ac45"
+ integrity sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==
-eslint-plugin-standard@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4"
- integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==
-
-eslint-scope@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
- integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==
- dependencies:
- esrecurse "^4.1.0"
- estraverse "^4.1.1"
+eslint-plugin-standard@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5"
+ integrity sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==
-eslint-scope@^5.0.0, eslint-scope@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5"
- integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==
+eslint-scope@^5.0.0, eslint-scope@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
+ integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
dependencies:
- esrecurse "^4.1.0"
+ esrecurse "^4.3.0"
estraverse "^4.1.1"
-eslint-utils@^1.3.1:
- version "1.4.3"
- resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
- integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==
- dependencies:
- eslint-visitor-keys "^1.1.0"
-
eslint-utils@^2.0.0, eslint-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
@@ -2631,75 +3377,42 @@ eslint-utils@^2.0.0, eslint-utils@^2.1.0:
dependencies:
eslint-visitor-keys "^1.1.0"
-eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
+eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
-eslint@^5.6.0:
- version "5.16.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea"
- integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- ajv "^6.9.1"
- chalk "^2.1.0"
- cross-spawn "^6.0.5"
- debug "^4.0.1"
- doctrine "^3.0.0"
- eslint-scope "^4.0.3"
- eslint-utils "^1.3.1"
- eslint-visitor-keys "^1.0.0"
- espree "^5.0.1"
- esquery "^1.0.1"
- esutils "^2.0.2"
- file-entry-cache "^5.0.1"
- functional-red-black-tree "^1.0.1"
- glob "^7.1.2"
- globals "^11.7.0"
- ignore "^4.0.6"
- import-fresh "^3.0.0"
- imurmurhash "^0.1.4"
- inquirer "^6.2.2"
- js-yaml "^3.13.0"
- json-stable-stringify-without-jsonify "^1.0.1"
- levn "^0.3.0"
- lodash "^4.17.11"
- minimatch "^3.0.4"
- mkdirp "^0.5.1"
- natural-compare "^1.4.0"
- optionator "^0.8.2"
- path-is-inside "^1.0.2"
- progress "^2.0.0"
- regexpp "^2.0.1"
- semver "^5.5.1"
- strip-ansi "^4.0.0"
- strip-json-comments "^2.0.1"
- table "^5.2.3"
- text-table "^0.2.0"
+eslint-visitor-keys@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
+ integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
-eslint@^7.5.0:
- version "7.5.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.5.0.tgz#9ecbfad62216d223b82ac9ffea7ef3444671d135"
- integrity sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==
+eslint@7.32.0:
+ version "7.32.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
+ integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
dependencies:
- "@babel/code-frame" "^7.0.0"
+ "@babel/code-frame" "7.12.11"
+ "@eslint/eslintrc" "^0.4.3"
+ "@humanwhocodes/config-array" "^0.5.0"
ajv "^6.10.0"
chalk "^4.0.0"
cross-spawn "^7.0.2"
debug "^4.0.1"
doctrine "^3.0.0"
enquirer "^2.3.5"
- eslint-scope "^5.1.0"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^5.1.1"
eslint-utils "^2.1.0"
- eslint-visitor-keys "^1.3.0"
- espree "^7.2.0"
- esquery "^1.2.0"
+ eslint-visitor-keys "^2.0.0"
+ espree "^7.3.1"
+ esquery "^1.4.0"
esutils "^2.0.2"
- file-entry-cache "^5.0.1"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^6.0.1"
functional-red-black-tree "^1.0.1"
- glob-parent "^5.0.0"
- globals "^12.1.0"
+ glob-parent "^5.1.2"
+ globals "^13.6.0"
ignore "^4.0.6"
import-fresh "^3.0.0"
imurmurhash "^0.1.4"
@@ -2707,7 +3420,7 @@ eslint@^7.5.0:
js-yaml "^3.13.1"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.4.1"
- lodash "^4.17.19"
+ lodash.merge "^4.6.2"
minimatch "^3.0.4"
natural-compare "^1.4.0"
optionator "^0.9.1"
@@ -2716,26 +3429,17 @@ eslint@^7.5.0:
semver "^7.2.1"
strip-ansi "^6.0.0"
strip-json-comments "^3.1.0"
- table "^5.2.3"
+ table "^6.0.9"
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
-espree@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a"
- integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==
- dependencies:
- acorn "^6.0.7"
- acorn-jsx "^5.0.0"
- eslint-visitor-keys "^1.0.0"
-
-espree@^7.2.0:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/espree/-/espree-7.2.0.tgz#1c263d5b513dbad0ac30c4991b93ac354e948d69"
- integrity sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==
+espree@^7.3.0, espree@^7.3.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
+ integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==
dependencies:
- acorn "^7.3.1"
- acorn-jsx "^5.2.0"
+ acorn "^7.4.0"
+ acorn-jsx "^5.3.1"
eslint-visitor-keys "^1.3.0"
esprima-extract-comments@^1.1.0:
@@ -2748,41 +3452,41 @@ esprima-extract-comments@^1.1.0:
esprima@2.7.x, esprima@^2.7.1:
version "2.7.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
- integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=
+ integrity sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
-esquery@^1.0.1, esquery@^1.2.0:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57"
- integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==
+esquery@^1.4.0:
+ 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.1.0:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
- integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
+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 "^4.1.0"
+ estraverse "^5.2.0"
estraverse@^1.9.1:
version "1.9.3"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
- integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=
+ integrity sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==
-estraverse@^4.1.0, estraverse@^4.1.1:
+estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
-estraverse@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642"
- integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==
+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"
@@ -2792,81 +3496,38 @@ esutils@^2.0.2:
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
- integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
-
-eth-block-tracker@^4.2.0:
- version "4.4.3"
- resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-4.4.3.tgz#766a0a0eb4a52c867a28328e9ae21353812cf626"
- integrity sha512-A8tG4Z4iNg4mw5tP1Vung9N9IjgMNqpiMoJ/FouSFwNCGHv2X0mmOYwtQOJzki6XN7r7Tyo01S29p7b224I4jw==
- dependencies:
- "@babel/plugin-transform-runtime" "^7.5.5"
- "@babel/runtime" "^7.5.5"
- eth-query "^2.1.0"
- json-rpc-random-id "^1.0.1"
- pify "^3.0.0"
- safe-event-emitter "^1.0.1"
+ integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
-eth-ens-namehash@2.0.8:
+eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.0, eth-ens-namehash@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf"
- integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88=
+ integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==
dependencies:
idna-uts46-hx "^2.3.1"
js-sha3 "^0.5.7"
-eth-json-rpc-errors@^1.0.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-errors/-/eth-json-rpc-errors-1.1.1.tgz#148377ef55155585981c21ff574a8937f9d6991f"
- integrity sha512-WT5shJ5KfNqHi9jOZD+ID8I1kuYWNrigtZat7GOQkvwo99f8SzAVaEcWhJUv656WiZOAg3P1RiJQANtUmDmbIg==
- dependencies:
- fast-safe-stringify "^2.0.6"
-
-eth-json-rpc-errors@^2.0.1:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-errors/-/eth-json-rpc-errors-2.0.2.tgz#c1965de0301fe941c058e928bebaba2e1285e3c4"
- integrity sha512-uBCRM2w2ewusRHGxN8JhcuOb2RN3ueAOYH/0BhqdFmQkZx5lj5+fLKTz0mIVOzd4FG5/kUksCzCD7eTEim6gaA==
- dependencies:
- fast-safe-stringify "^2.0.6"
-
-eth-json-rpc-infura@^3.1.0:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f"
- integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==
- dependencies:
- cross-fetch "^2.1.1"
- eth-json-rpc-middleware "^1.5.0"
- json-rpc-engine "^3.4.0"
- json-rpc-error "^2.0.0"
-
-eth-json-rpc-middleware@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f"
- integrity sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==
- dependencies:
- async "^2.5.0"
- eth-query "^2.1.2"
- eth-tx-summary "^3.1.2"
- ethereumjs-block "^1.6.0"
- ethereumjs-tx "^1.3.3"
- ethereumjs-util "^5.1.2"
- ethereumjs-vm "^2.1.0"
- fetch-ponyfill "^4.0.0"
- json-rpc-engine "^3.6.0"
- json-rpc-error "^2.0.0"
- json-stable-stringify "^1.0.1"
- promise-to-callback "^1.0.0"
- tape "^4.6.3"
-
-eth-lib@0.2.7:
- version "0.2.7"
- resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca"
- integrity sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=
- dependencies:
- bn.js "^4.11.6"
- elliptic "^6.4.0"
- xhr-request-promise "^0.1.2"
-
-eth-lib@0.2.8, eth-lib@^0.2.8:
+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==
+ dependencies:
+ "@ethersproject/abi" "^5.0.0-beta.146"
+ "@solidity-parser/parser" "^0.14.0"
+ cli-table3 "^0.5.0"
+ colors "1.4.0"
+ ethereum-cryptography "^1.0.3"
+ ethers "^4.0.40"
+ fs-readdir-recursive "^1.1.0"
+ lodash "^4.17.14"
+ markdown-table "^1.1.3"
+ mocha "^7.1.1"
+ req-cwd "^2.0.0"
+ request "^2.88.0"
+ request-promise-native "^1.0.5"
+ sha1 "^1.1.1"
+ sync-request "^6.0.0"
+
+eth-lib@0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8"
integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==
@@ -2887,48 +3548,14 @@ eth-lib@^0.1.26:
ws "^3.0.0"
xhr-request-promise "^0.1.2"
-eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e"
- integrity sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=
- dependencies:
- json-rpc-random-id "^1.0.0"
- xtend "^4.0.1"
-
-eth-tx-summary@^3.1.2:
- version "3.2.4"
- resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c"
- integrity sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==
- dependencies:
- async "^2.1.2"
- clone "^2.0.0"
- concat-stream "^1.5.1"
- end-of-stream "^1.1.0"
- eth-query "^2.0.2"
- ethereumjs-block "^1.4.1"
- ethereumjs-tx "^1.1.1"
- ethereumjs-util "^5.0.1"
- ethereumjs-vm "^2.6.0"
- through2 "^2.0.3"
-
ethereum-bloom-filters@^1.0.6:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz#b7b80735e385dbb7f944ce6b4533e24511306060"
- integrity sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a"
+ integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==
dependencies:
js-sha3 "^0.8.0"
-ethereum-common@0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca"
- integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==
-
-ethereum-common@^0.0.18:
- version "0.0.18"
- resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f"
- integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=
-
-ethereum-cryptography@^0.1.3:
+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==
@@ -2949,98 +3576,58 @@ ethereum-cryptography@^0.1.3:
secp256k1 "^4.0.1"
setimmediate "^1.0.5"
-ethereum-protocol@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/ethereum-protocol/-/ethereum-protocol-1.0.1.tgz#b7d68142f4105e0ae7b5e178cf42f8d4dc4b93cf"
- integrity sha512-3KLX1mHuEsBW0dKG+c6EOJS1NBNqdCICvZW9sInmZTt5aY0oxmHVggYRE0lJu1tcnMD1K+AKHdLi6U43Awm1Vg==
-
-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-account@^2.0.3:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84"
- integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==
- dependencies:
- ethereumjs-util "^5.0.0"
- rlp "^2.0.0"
- safe-buffer "^5.1.1"
-
-ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0:
- version "1.7.1"
- resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f"
- integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==
+ethereum-cryptography@^1.0.3:
+ 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:
- async "^2.0.1"
- ethereum-common "0.2.0"
- ethereumjs-tx "^1.2.2"
- ethereumjs-util "^5.0.0"
- merkle-patricia-tree "^2.1.2"
+ "@noble/hashes" "1.2.0"
+ "@noble/secp256k1" "1.7.1"
+ "@scure/bip32" "1.1.5"
+ "@scure/bip39" "1.1.1"
-ethereumjs-block@~2.2.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965"
- integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==
+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:
- async "^2.0.1"
- ethereumjs-common "^1.5.0"
- ethereumjs-tx "^2.1.1"
- ethereumjs-util "^5.0.0"
- merkle-patricia-tree "^2.1.2"
+ "@noble/curves" "1.1.0"
+ "@noble/hashes" "1.3.1"
+ "@scure/bip32" "1.3.1"
+ "@scure/bip39" "1.2.1"
-ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.1.tgz#4e75042473a64daec0ed9fe84323dd9576aa5dba"
- integrity sha512-aVUPRLgmXORGXXEVkFYgPhr9TGtpBY2tGhZ9Uh0A3lIUzUDr1x6kQx33SbjPUkLkX3eniPQnIL/2psjkjrOfcQ==
-
-ethereumjs-tx@^1.0.0, ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3, ethereumjs-tx@^1.3.7:
- version "1.3.7"
- resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a"
- integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==
+ethereum-ens@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/ethereum-ens/-/ethereum-ens-0.8.0.tgz#6d0f79acaa61fdbc87d2821779c4e550243d4c57"
+ integrity sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==
dependencies:
- ethereum-common "^0.0.18"
- ethereumjs-util "^5.0.0"
+ bluebird "^3.4.7"
+ eth-ens-namehash "^2.0.0"
+ js-sha3 "^0.5.7"
+ pako "^1.0.4"
+ underscore "^1.8.3"
+ web3 "^1.0.0-beta.34"
-ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed"
- integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==
+ethereumjs-abi@0.6.8, 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:
- ethereumjs-common "^1.5.0"
+ bn.js "^4.11.8"
ethereumjs-util "^6.0.0"
-ethereumjs-util@6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8"
- integrity sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==
- dependencies:
- bn.js "^4.11.0"
- create-hash "^1.1.2"
- ethjs-util "0.1.6"
- keccak "^1.0.2"
- rlp "^2.0.0"
- safe-buffer "^5.1.1"
- secp256k1 "^3.0.1"
-
-ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.5:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65"
- integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==
+ethereumjs-util@7.1.5, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5:
+ version "7.1.5"
+ resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181"
+ integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==
dependencies:
- bn.js "^4.11.0"
+ "@types/bn.js" "^5.1.0"
+ bn.js "^5.1.2"
create-hash "^1.1.2"
- elliptic "^6.5.2"
ethereum-cryptography "^0.1.3"
- ethjs-util "^0.1.3"
- rlp "^2.0.0"
- safe-buffer "^5.1.1"
+ rlp "^2.2.4"
-ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.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==
@@ -3053,74 +3640,27 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0:
ethjs-util "0.1.6"
rlp "^2.2.3"
-ethereumjs-util@^7.0.3:
- version "7.0.3"
- resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.3.tgz#d055fc7f852d79065d2e689002a789b1323cf3fd"
- integrity sha512-uLQsGPOwsRxe50WV1Dybh5N8zXDz4ev7wP49LKX9kr28I5TmcDILPgpKK/BFe5zYSfRGEeo+hPT7W3tjghYLuA==
- dependencies:
- "@types/bn.js" "^4.11.3"
- bn.js "^5.1.2"
- create-hash "^1.1.2"
- ethereum-cryptography "^0.1.3"
- ethjs-util "0.1.6"
- rlp "^2.2.4"
-
-ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0:
- version "2.6.0"
- resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6"
- integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==
- dependencies:
- async "^2.1.2"
- async-eventemitter "^0.2.2"
- ethereumjs-account "^2.0.3"
- ethereumjs-block "~2.2.0"
- ethereumjs-common "^1.1.0"
- ethereumjs-util "^6.0.0"
- fake-merkle-patricia-tree "^1.0.1"
- functional-red-black-tree "^1.0.1"
- merkle-patricia-tree "^2.3.2"
- rustbn.js "~0.2.0"
- safe-buffer "^5.1.1"
-
-ethereumjs-wallet@^0.6.3:
- version "0.6.5"
- resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474"
- integrity sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==
- dependencies:
- aes-js "^3.1.1"
- bs58check "^2.1.2"
- ethereum-cryptography "^0.1.3"
- ethereumjs-util "^6.0.0"
- randombytes "^2.0.6"
- safe-buffer "^5.1.2"
- scryptsy "^1.2.1"
- utf8 "^3.0.0"
- uuid "^3.3.2"
-
-ethers@4.0.0-beta.3:
- version "4.0.0-beta.3"
- resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066"
- integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog==
+ethers@6.11.1:
+ version "6.11.1"
+ resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.11.1.tgz#96aae00b627c2e35f9b0a4d65c7ab658259ee6af"
+ integrity sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==
dependencies:
- "@types/node" "^10.3.2"
- aes-js "3.0.0"
- bn.js "^4.4.0"
- elliptic "6.3.3"
- hash.js "1.1.3"
- js-sha3 "0.5.7"
- scrypt-js "2.0.3"
- setimmediate "1.0.4"
- uuid "2.0.1"
- xmlhttprequest "1.8.0"
+ "@adraffy/ens-normalize" "1.10.1"
+ "@noble/curves" "1.2.0"
+ "@noble/hashes" "1.3.2"
+ "@types/node" "18.15.13"
+ aes-js "4.0.0-beta.5"
+ tslib "2.4.0"
+ ws "8.5.0"
-ethers@^4.0.32:
- version "4.0.47"
- resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.47.tgz#91b9cd80473b1136dd547095ff9171bd1fc68c85"
- integrity sha512-hssRYhngV4hiDNeZmVU/k5/E8xmLG8UpcNUzg6mb7lqhgpFPH/t7nuv20RjRrEf0gblzvi2XwR5Te+V3ZFc9pQ==
+ethers@^4.0.0-beta.1, ethers@^4.0.32, 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.4.0"
- elliptic "6.5.2"
+ bn.js "^4.11.9"
+ elliptic "6.5.4"
hash.js "1.1.3"
js-sha3 "0.5.7"
scrypt-js "2.0.4"
@@ -3128,15 +3668,51 @@ ethers@^4.0.32:
uuid "2.0.1"
xmlhttprequest "1.8.0"
+ethers@^5.0.13, 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-unit@0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699"
- integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=
+ integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==
dependencies:
bn.js "4.11.6"
number-to-bn "1.7.0"
-ethjs-util@0.1.6, ethjs-util@^0.1.3:
+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==
@@ -3144,27 +3720,12 @@ ethjs-util@0.1.6, ethjs-util@^0.1.3:
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==
-
-eventemitter3@3.1.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
- integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
-
eventemitter3@4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384"
integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==
-events@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
- integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==
-
-evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
+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==
@@ -3172,76 +3733,55 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
-execa@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
- integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
- dependencies:
- cross-spawn "^6.0.0"
- get-stream "^4.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
express@^4.14.0:
- version "4.17.1"
- resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
- integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
+ version "4.18.2"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
+ integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
dependencies:
- accepts "~1.3.7"
+ accepts "~1.3.8"
array-flatten "1.1.1"
- body-parser "1.19.0"
- content-disposition "0.5.3"
+ body-parser "1.20.1"
+ content-disposition "0.5.4"
content-type "~1.0.4"
- cookie "0.4.0"
+ cookie "0.5.0"
cookie-signature "1.0.6"
debug "2.6.9"
- depd "~1.1.2"
+ depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
- finalhandler "~1.1.2"
+ finalhandler "1.2.0"
fresh "0.5.2"
+ http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
- on-finished "~2.3.0"
+ on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
- proxy-addr "~2.0.5"
- qs "6.7.0"
+ proxy-addr "~2.0.7"
+ qs "6.11.0"
range-parser "~1.2.1"
- safe-buffer "5.1.2"
- send "0.17.1"
- serve-static "1.14.1"
- setprototypeof "1.1.1"
- statuses "~1.5.0"
+ safe-buffer "5.2.1"
+ send "0.18.0"
+ serve-static "1.15.0"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244"
- integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
+ integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==
dependencies:
- type "^2.0.0"
+ type "^2.7.2"
-extend@^3.0.2, extend@~3.0.2:
+extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
-external-editor@^3.0.3:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
- integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
- dependencies:
- chardet "^0.7.0"
- iconv-lite "^0.4.24"
- tmp "^0.0.33"
-
extract-comments@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/extract-comments/-/extract-comments-1.1.0.tgz#b90bca033a056bd69b8ba1c6b6b120fc2ee95c18"
@@ -3253,41 +3793,40 @@ extract-comments@^1.1.0:
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
- integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
+ integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
extsprintf@^1.2.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
- integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
+ integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
-fake-merkle-patricia-tree@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3"
- integrity sha1-S4w6z7Ugr635hgsfFM2M40As3dM=
+fast-check@3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.1.tgz#72c5ae7022a4e86504762e773adfb8a5b0b01252"
+ integrity sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA==
dependencies:
- checkpoint-store "^1.1.0"
+ pure-rand "^5.0.1"
-fast-deep-equal@^3.1.1:
+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:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
- integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
+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.0.3:
- version "3.2.4"
- resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3"
- integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==
+ 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.0"
+ glob-parent "^5.1.2"
merge2 "^1.3.0"
- micromatch "^4.0.2"
- picomatch "^2.2.1"
+ micromatch "^4.0.4"
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
@@ -3297,72 +3836,21 @@ fast-json-stable-stringify@^2.0.0:
fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
- integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
-
-fast-safe-stringify@^2.0.6:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
- integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
-
-fast-text-encoding@^1.0.0:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53"
- integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==
+ integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fastq@^1.6.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
- integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==
+ 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"
-fd-slicer@~1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
- integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
- dependencies:
- pend "~1.2.0"
-
-fetch-ponyfill@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893"
- integrity sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=
- dependencies:
- node-fetch "~1.7.1"
-
-figures@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
- integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
- dependencies:
- escape-string-regexp "^1.0.5"
-
-file-entry-cache@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c"
- integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==
+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 "^2.0.1"
-
-file-type@^3.8.0:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
- integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek=
-
-file-type@^5.2.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6"
- integrity sha1-LdvqfHP/42No365J3DOMBYwritY=
-
-file-type@^6.1.0:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919"
- integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==
-
-file-uri-to-path@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
- integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
+ flat-cache "^3.0.4"
fill-range@^7.0.1:
version "7.0.1"
@@ -3371,71 +3859,88 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
-finalhandler@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
- integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
+finalhandler@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
+ integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
dependencies:
debug "2.6.9"
encodeurl "~1.0.2"
escape-html "~1.0.3"
- on-finished "~2.3.0"
+ on-finished "2.4.1"
parseurl "~1.3.3"
- statuses "~1.5.0"
+ statuses "2.0.1"
unpipe "~1.0.0"
-find-replace@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0"
- integrity sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=
+find-replace@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38"
+ integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==
dependencies:
- array-back "^1.0.4"
- test-value "^2.1.0"
+ array-back "^3.0.1"
-find-up@4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
- integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
+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 "^5.0.0"
+ locate-path "^3.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.0.0, find-up@^2.1.0:
+find-up@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
+ integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==
+ dependencies:
+ path-exists "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
- integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
+ integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==
dependencies:
locate-path "^2.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==
+find-up@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
+ integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
dependencies:
- locate-path "^3.0.0"
+ locate-path "^5.0.0"
+ path-exists "^4.0.0"
-flat-cache@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
- integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==
+flat-cache@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
+ integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
dependencies:
- flatted "^2.0.0"
- rimraf "2.6.3"
- write "1.0.3"
+ flatted "^3.1.0"
+ rimraf "^3.0.2"
-flat@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2"
- integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==
- dependencies:
- is-buffer "~2.0.3"
+flat@5.0.2, flat@^4.1.0, 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@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
- integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
+flatted@^3.1.0:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
+ integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
+
+follow-redirects@^1.12.1:
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
+ integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
-for-each@~0.3.3:
+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==
@@ -3445,7 +3950,21 @@ for-each@~0.3.3:
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
- integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
+ integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
+
+form-data-encoder@1.7.1:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96"
+ integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==
+
+form-data@^2.2.0:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
+ integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.6"
+ mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
@@ -3456,25 +3975,30 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
-forwarded@~0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
- integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
+forwarded@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
+ integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
+
+fp-ts@1.19.3:
+ version "1.19.3"
+ resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f"
+ 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==
fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
- integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
-
-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==
+ integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
fs-extra@^0.30.0:
version "0.30.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
- integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=
+ integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^2.1.0"
@@ -3491,7 +4015,7 @@ fs-extra@^4.0.2:
jsonfile "^4.0.0"
universalify "^0.1.0"
-fs-extra@^7.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==
@@ -3509,71 +4033,79 @@ fs-extra@^8.1.0:
jsonfile "^4.0.0"
universalify "^0.1.0"
-fs-minipass@^1.2.5:
+fs-extra@^9.1.0:
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
+ integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
+ dependencies:
+ at-least-node "^1.0.0"
+ graceful-fs "^4.2.0"
+ jsonfile "^6.0.1"
+ universalify "^2.0.0"
+
+fs-minipass@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
dependencies:
minipass "^2.6.0"
+fs-readdir-recursive@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
+ integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==
+
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
- integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
+ integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
-fsevents@~2.1.2:
+fsevents@~2.1.1:
version "2.1.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
-function-bind@^1.1.1, function-bind@~1.1.1:
+fsevents@~2.3.2:
+ 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.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-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 sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+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==
-ganache-cli@6.9.0:
- version "6.9.0"
- resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.9.0.tgz#94d7e26964dff80b7382a33829ec75e15709a948"
- integrity sha512-ZdL6kPrApXF/O+f6uU431OJcwxMk69H3KPDSHHrMP82ZvZRNpDHbR+rVv7XX/YUeoQ5q6nZ2AFiGiFAVn9pfzA==
+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:
- ethereumjs-util "6.1.0"
- source-map-support "0.5.12"
- yargs "13.2.4"
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.0"
+ functions-have-names "^1.2.2"
-ganache-cli@^6.9.1:
- version "6.9.1"
- resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.9.1.tgz#1e13eee098fb9f19b031a191ec3f62ae926ea8b3"
- integrity sha512-VPBumkNUZzXDRQwVOby5YyQpd5t1clkr06xMgB28lZdEIn5ht1GMwUskOTFOAxdkQ4J12IWP0gdeacVRGowqbA==
- dependencies:
- ethereumjs-util "6.1.0"
- source-map-support "0.5.12"
- yargs "13.2.4"
+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==
-gaxios@^3.0.0:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-3.0.4.tgz#4714fbb003d6f6f08a297f772284463e041e04db"
- integrity sha512-97NmFuMETFQh6gqPUxkqjxRMjmY8aRKRMphIkgO/b90AbCt5wAVuXsp8oWjIXlLN2pIK/fsXD8edcM7ULkFMLg==
- dependencies:
- abort-controller "^3.0.0"
- extend "^3.0.2"
- https-proxy-agent "^5.0.0"
- is-stream "^2.0.0"
- node-fetch "^2.3.0"
+functions-have-names@^1.2.2, 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==
-gcp-metadata@^4.1.0:
- version "4.1.4"
- resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-4.1.4.tgz#3adadb9158c716c325849ee893741721a3c09e7e"
- integrity sha512-5J/GIH0yWt/56R3dNaNWPGQ/zXsZOddYECfJaqxFWgrZ9HC2Kvc5vl9upOgUUHKzURjAVf2N+f6tEJiojqXUuA==
- dependencies:
- gaxios "^3.0.0"
- json-bigint "^1.0.0"
+get-caller-file@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
+ integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
-get-caller-file@^2.0.1:
+get-caller-file@^2.0.1, 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==
@@ -3581,44 +4113,52 @@ get-caller-file@^2.0.1:
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 sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
+ integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
+
+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:
+ 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-port@^3.1.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc"
+ integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==
get-stdin@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==
-get-stream@^2.2.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
- integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=
- dependencies:
- object-assign "^4.0.1"
- pinkie-promise "^2.0.0"
-
-get-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
- integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
-
-get-stream@^4.0.0, get-stream@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
- integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
+get-stream@^5.1.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
+ integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
dependencies:
pump "^3.0.0"
-get-stream@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9"
- integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
+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:
- pump "^3.0.0"
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.1"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
- integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
+ integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
dependencies:
assert-plus "^1.0.0"
@@ -3630,17 +4170,41 @@ ghost-testrpc@^0.0.2:
chalk "^2.4.2"
node-emoji "^1.10.0"
-glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
- integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
+glob-parent@^5.1.2, glob-parent@~5.1.0, 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@7.1.6, glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6, glob@~7.1.6:
- version "7.1.6"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
- integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
+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.1.7:
+ version "7.1.7"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
+ integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
+ 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"
+ integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
@@ -3649,10 +4213,21 @@ glob@7.1.6, glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6, glob@~7.1.6:
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@8.1.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@^5.0.15:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
- integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=
+ integrity sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==
dependencies:
inflight "^1.0.4"
inherits "2"
@@ -3660,6 +4235,18 @@ glob@^5.0.15:
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^7.0.0, glob@^7.1.3, glob@^7.1.6:
+ 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"
+
global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
@@ -3676,30 +4263,27 @@ global-prefix@^3.0.0:
kind-of "^6.0.2"
which "^1.3.1"
-global@~4.3.0:
- version "4.3.2"
- resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
- integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=
+global@~4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
+ integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
dependencies:
min-document "^2.19.0"
- process "~0.5.1"
-
-globals@^11.7.0:
- version "11.12.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
- integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+ process "^0.11.10"
-globals@^12.1.0:
- version "12.4.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8"
- integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==
+globals@^13.6.0, globals@^13.9.0:
+ version "13.20.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82"
+ integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==
dependencies:
- type-fest "^0.8.1"
+ type-fest "^0.20.2"
-globals@^9.18.0:
- version "9.18.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
- integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
+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@^10.0.1:
version "10.0.2"
@@ -3715,114 +4299,71 @@ globby@^10.0.1:
merge2 "^1.2.3"
slash "^3.0.0"
-google-auth-library@^6.0.0:
- version "6.0.5"
- resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-6.0.5.tgz#f7266859dbb02dadf92af479272fb1e344635cb5"
- integrity sha512-Wj31lfTm2yR4g3WfOOB1Am1tt478Xq9OvzTPQJi17tn/I9R5IcsxjANBsE93nYmxYxtwDedhOdIb8l3vSPG49Q==
- dependencies:
- arrify "^2.0.0"
- base64-js "^1.3.0"
- ecdsa-sig-formatter "^1.0.11"
- fast-text-encoding "^1.0.0"
- gaxios "^3.0.0"
- gcp-metadata "^4.1.0"
- gtoken "^5.0.0"
- jws "^4.0.0"
- lru-cache "^6.0.0"
-
-google-p12-pem@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.0.2.tgz#12d443994b6f4cd8c9e4ac479f2f18d4694cbdb8"
- integrity sha512-tbjzndQvSIHGBLzHnhDs3cL4RBjLbLXc2pYvGH+imGVu5b4RMAttUTdnmW2UH0t11QeBTXZ7wlXPS7hrypO/tg==
- dependencies:
- node-forge "^0.9.0"
-
-googleapis-common@^4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/googleapis-common/-/googleapis-common-4.4.0.tgz#b806e41c4e883f22b68769aafb3ed11802919091"
- integrity sha512-Bgrs8/1OZQFFIfVuX38L9t48rPAkVUXttZy6NzhhXxFOEMSHgfFIjxou7RIXOkBHxmx2pVwct9WjKkbnqMYImQ==
- dependencies:
- extend "^3.0.2"
- gaxios "^3.0.0"
- google-auth-library "^6.0.0"
- qs "^6.7.0"
- url-template "^2.0.8"
- uuid "^8.0.0"
-
-googleapis@^55.0.0:
- version "55.0.0"
- resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-55.0.0.tgz#02c7062bc9e40d55e8dc6ebcedc8831ad5edd04a"
- integrity sha512-bjeEjI2183eU0RsPIYsVOQJpjJvPprdCFe6AtjT32SBYX7GW2rZgRP9Qna8aCbDEutyJjP8uBscirkDDpWLhQw==
- dependencies:
- google-auth-library "^6.0.0"
- googleapis-common "^4.4.0"
-
-got@9.6.0:
- version "9.6.0"
- resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
- integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
- dependencies:
- "@sindresorhus/is" "^0.14.0"
- "@szmarczak/http-timer" "^1.1.2"
- cacheable-request "^6.0.0"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^4.1.0"
- lowercase-keys "^1.0.1"
- mimic-response "^1.0.1"
- p-cancelable "^1.0.0"
- to-readable-stream "^1.0.0"
- url-parse-lax "^3.0.0"
-
-got@^7.1.0:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
- integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==
- dependencies:
- decompress-response "^3.2.0"
- duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- is-plain-obj "^1.1.0"
- is-retry-allowed "^1.0.0"
- is-stream "^1.0.0"
- isurl "^1.0.0-alpha5"
- lowercase-keys "^1.0.0"
- p-cancelable "^0.3.0"
- p-timeout "^1.1.1"
- safe-buffer "^5.0.1"
- timed-out "^4.0.0"
- url-parse-lax "^1.0.0"
- url-to-options "^1.0.1"
-
-graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0:
- version "4.2.4"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
- integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
-
-"graceful-readlink@>= 1.0.0":
+gopd@^1.0.1:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
- integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
+ resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
+ integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+ dependencies:
+ get-intrinsic "^1.1.3"
+
+got@12.1.0:
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4"
+ integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==
+ dependencies:
+ "@sindresorhus/is" "^4.6.0"
+ "@szmarczak/http-timer" "^5.0.1"
+ "@types/cacheable-request" "^6.0.2"
+ "@types/responselike" "^1.0.0"
+ cacheable-lookup "^6.0.4"
+ cacheable-request "^7.0.2"
+ decompress-response "^6.0.0"
+ form-data-encoder "1.7.1"
+ get-stream "^6.0.1"
+ http2-wrapper "^2.1.10"
+ lowercase-keys "^3.0.0"
+ p-cancelable "^3.0.0"
+ responselike "^2.0.0"
+
+got@^11.8.5:
+ version "11.8.6"
+ resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a"
+ integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==
+ dependencies:
+ "@sindresorhus/is" "^4.0.0"
+ "@szmarczak/http-timer" "^4.0.5"
+ "@types/cacheable-request" "^6.0.1"
+ "@types/responselike" "^1.0.0"
+ cacheable-lookup "^5.0.3"
+ cacheable-request "^7.0.2"
+ decompress-response "^6.0.0"
+ http2-wrapper "^1.0.0-beta.5.2"
+ lowercase-keys "^2.0.0"
+ p-cancelable "^2.0.0"
+ responselike "^2.0.0"
+
+graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0:
+ 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==
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==
-gtoken@^5.0.0:
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.0.2.tgz#688e4334b99378b4d4a67add19e1680f411ba74d"
- integrity sha512-lull70rHCTvRTmAt+R/6W5bTtx4MjHku7AwJwK5fGqhOmygcZud0nrZcX+QUNfBJwCzqy7S5i1Bc4NYnr5PMMA==
+hamt-sharding@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/hamt-sharding/-/hamt-sharding-2.0.1.tgz#f45686d0339e74b03b233bee1bde9587727129b6"
+ integrity sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA==
dependencies:
- gaxios "^3.0.0"
- google-p12-pem "^3.0.0"
- jws "^4.0.0"
- mime "^2.2.0"
+ sparse-array "^1.3.1"
+ uint8arrays "^3.0.0"
handlebars@^4.0.1:
- version "4.7.6"
- resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e"
- integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==
+ 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==
dependencies:
minimist "^1.2.5"
neo-async "^2.6.0"
@@ -3834,56 +4375,138 @@ handlebars@^4.0.1:
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
- integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
+ integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==
har-validator@~5.1.3:
- version "5.1.3"
- resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
- integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
+ version "5.1.5"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
+ integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
dependencies:
- ajv "^6.5.5"
+ ajv "^6.12.3"
har-schema "^2.0.0"
-has-ansi@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
- integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
+hard-rejection@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
+ integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==
+
+hardhat-contract-sizer@2.10.0:
+ 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:
- ansi-regex "^2.0.0"
+ chalk "^4.0.0"
+ cli-table3 "^0.6.0"
+ strip-ansi "^6.0.0"
+
+hardhat-gas-reporter@1.0.10:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz#ebe5bda5334b5def312747580cd923c2b09aef1b"
+ integrity sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==
+ dependencies:
+ array-uniq "1.0.3"
+ eth-gas-reporter "^0.2.25"
+ sha1 "^1.1.1"
+
+hardhat@2.19.4:
+ version "2.19.4"
+ resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.4.tgz#5112c30295d8be2e18e55d847373c50483ed1902"
+ integrity sha512-fTQJpqSt3Xo9Mn/WrdblNGAfcANM6XC3tAEi6YogB4s02DmTf93A8QsGb8uR0KR8TFcpcS8lgiW4ugAIYpnbrQ==
+ dependencies:
+ "@ethersproject/abi" "^5.1.2"
+ "@metamask/eth-sig-util" "^4.0.0"
+ "@nomicfoundation/ethereumjs-block" "5.0.2"
+ "@nomicfoundation/ethereumjs-blockchain" "7.0.2"
+ "@nomicfoundation/ethereumjs-common" "4.0.2"
+ "@nomicfoundation/ethereumjs-evm" "2.0.2"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.2"
+ "@nomicfoundation/ethereumjs-statemanager" "2.0.2"
+ "@nomicfoundation/ethereumjs-trie" "6.0.2"
+ "@nomicfoundation/ethereumjs-tx" "5.0.2"
+ "@nomicfoundation/ethereumjs-util" "9.0.2"
+ "@nomicfoundation/ethereumjs-vm" "7.0.2"
+ "@nomicfoundation/solidity-analyzer" "^0.1.0"
+ "@sentry/node" "^5.18.1"
+ "@types/bn.js" "^5.1.0"
+ "@types/lru-cache" "^5.1.0"
+ adm-zip "^0.4.16"
+ aggregate-error "^3.0.0"
+ ansi-escapes "^4.3.0"
+ 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@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
- integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
+ integrity sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
- integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+ 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-symbol-support-x@^1.4.1:
- version "1.4.2"
- resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
- integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
+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==
+ dependencies:
+ get-intrinsic "^1.1.1"
-has-symbols@^1.0.0, has-symbols@^1.0.1:
+has-proto@^1.0.1:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
- integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
+ integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
-has-to-string-tag-x@^1.2.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
- integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
+has-symbols@^1.0.0, has-symbols@^1.0.2, has-symbols@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
+ integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+
+has-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-symbol-support-x "^1.4.1"
+ has-symbols "^1.0.2"
-has@^1.0.3, 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==
@@ -3907,7 +4530,7 @@ hash.js@1.1.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.0"
-hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7:
+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==
@@ -3915,96 +4538,155 @@ hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"
+hasown@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
+ integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
+ 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.0:
+header-case@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d"
+ integrity sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==
+ dependencies:
+ no-case "^2.2.0"
+ upper-case "^1.1.3"
+
+"heap@>= 0.2.0":
+ version "0.2.7"
+ resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc"
+ integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==
+
+highlight.js@^10.4.1:
+ version "10.7.3"
+ resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
+ integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
+
+highlightjs-solidity@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-2.0.6.tgz#e7a702a2b05e0a97f185e6ba39fd4846ad23a990"
+ integrity sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg==
+
+hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
- integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
+ integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==
dependencies:
hash.js "^1.0.3"
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
-home-or-tmp@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
- integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg=
+hosted-git-info@^2.1.4:
+ version "2.8.9"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
+ integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
+
+hosted-git-info@^4.0.1:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224"
+ integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==
dependencies:
- os-homedir "^1.0.0"
- os-tmpdir "^1.0.1"
+ lru-cache "^6.0.0"
-hosted-git-info@^2.1.4:
- version "2.8.8"
- resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
- integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
+htmlparser2@^8.0.1:
+ version "8.0.2"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
+ integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
+ dependencies:
+ domelementtype "^2.3.0"
+ domhandler "^5.0.3"
+ domutils "^3.0.1"
+ entities "^4.4.0"
+
+http-basic@^8.1.1:
+ version "8.1.3"
+ resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf"
+ integrity sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==
+ dependencies:
+ caseless "^0.12.0"
+ concat-stream "^1.6.2"
+ http-response-object "^3.0.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==
-
-http-errors@1.7.2:
- version "1.7.2"
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
- integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
- dependencies:
- depd "~1.1.2"
- inherits "2.0.3"
- setprototypeof "1.1.1"
- statuses ">= 1.5.0 < 2"
- toidentifier "1.0.0"
-
-http-errors@~1.7.2:
- version "1.7.3"
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
- integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
- dependencies:
- depd "~1.1.2"
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
+ integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
+
+http-errors@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
+ integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
+ dependencies:
+ depd "2.0.0"
inherits "2.0.4"
- setprototypeof "1.1.1"
- statuses ">= 1.5.0 < 2"
- toidentifier "1.0.0"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
+ toidentifier "1.0.1"
http-https@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b"
- integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=
+ integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==
+
+http-response-object@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810"
+ integrity sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==
+ dependencies:
+ "@types/node" "^10.0.3"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
- integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
+ integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
+http2-wrapper@^1.0.0-beta.5.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
+ integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
+ dependencies:
+ quick-lru "^5.1.1"
+ resolve-alpn "^1.0.0"
+
+http2-wrapper@^2.1.10:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3"
+ integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==
+ dependencies:
+ quick-lru "^5.1.1"
+ resolve-alpn "^1.2.0"
+
https-proxy-agent@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
- integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
+ 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"
-iconv-lite@0.4.24, iconv-lite@^0.4.24:
+husky@8.0.3:
+ version "8.0.3"
+ resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184"
+ integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==
+
+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"
-iconv-lite@^0.6.2:
- version "0.6.2"
- resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01"
- integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==
- dependencies:
- safer-buffer ">= 2.1.2 < 3.0.0"
-
idna-uts46-hx@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9"
@@ -4012,38 +4694,30 @@ idna-uts46-hx@^2.3.1:
dependencies:
punycode "2.1.0"
-ieee754@^1.1.4:
- version "1.1.13"
- resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
- integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
+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@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-ignore@^5.1.1:
- version "5.1.8"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
- integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
+ignore@^5.1.1, ignore@^5.2.4:
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
+ integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
-immediate@^3.2.3:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266"
- integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==
-
-import-fresh@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
- integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
- dependencies:
- caller-path "^2.0.0"
- resolve-from "^3.0.0"
+immutable@^4.0.0-rc.12:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.2.tgz#f89d910f8dfb6e15c03b2cae2faaf8c1f66455fe"
+ integrity sha512-oGXzbEDem9OOpDWZu88jGiYCvIsLHMvGw+8OXlpsvTFvIQplQbjg1B1cvKg8f7Hoch6+NGjpPsH1Fr+Mc2D1aA==
-import-fresh@^3.0.0:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
- integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==
+import-fresh@^3.0.0, import-fresh@^3.2.1:
+ 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"
@@ -4051,81 +4725,148 @@ import-fresh@^3.0.0:
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
- integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+ 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 sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
+ 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, inherits@~2.0.4:
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, 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==
-inherits@2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
- integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
ini@^1.3.5:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
- integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
+ integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-inquirer@^6.2.2:
- version "6.5.2"
- resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"
- integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==
+interface-ipld-format@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/interface-ipld-format/-/interface-ipld-format-1.0.1.tgz#bee39c70c584a033e186ff057a2be89f215963e3"
+ integrity sha512-WV/ar+KQJVoQpqRDYdo7YPGYIUHJxCuOEhdvsRpzLqoOIVCqPKdMMYmsLL1nCRsF3yYNio+PAJbCKiv6drrEAg==
dependencies:
- ansi-escapes "^3.2.0"
- chalk "^2.4.2"
- cli-cursor "^2.1.0"
- cli-width "^2.0.0"
- external-editor "^3.0.3"
- figures "^2.0.0"
- lodash "^4.17.12"
- mute-stream "0.0.7"
- run-async "^2.2.0"
- rxjs "^6.4.0"
- string-width "^2.1.0"
- strip-ansi "^5.1.0"
- through "^2.3.6"
+ cids "^1.1.6"
+ multicodec "^3.0.1"
+ multihashes "^4.0.2"
+
+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==
+ dependencies:
+ get-intrinsic "^1.2.0"
+ has "^1.0.3"
+ side-channel "^1.0.4"
interpret@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
-invariant@^2.2.2:
- version "2.2.4"
- resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
- integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
- dependencies:
- loose-envify "^1.0.0"
+invert-kv@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
+ integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==
-invert-kv@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
- integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
+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"
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
+ipfs-only-hash@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/ipfs-only-hash/-/ipfs-only-hash-4.0.0.tgz#b3bd60a244d9eb7394961aa9d812a2e5ac7c04d6"
+ integrity sha512-TE1DZCvfw8i3gcsTq3P4TFx3cKFJ3sluu/J3XINkJhIN9OwJgNMqKA+WnKx6ByCb1IoPXsTp1KM7tupElb6SyA==
+ dependencies:
+ ipfs-unixfs-importer "^7.0.1"
+ meow "^9.0.0"
+
+ipfs-unixfs-importer@^7.0.1:
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/ipfs-unixfs-importer/-/ipfs-unixfs-importer-7.0.3.tgz#b850e831ca9647d589ef50bc33421f65bab7bba6"
+ integrity sha512-qeFOlD3AQtGzr90sr5Tq1Bi8pT5Nr2tSI8z310m7R4JDYgZc6J1PEZO3XZQ8l1kuGoqlAppBZuOYmPEqaHcVQQ==
+ dependencies:
+ bl "^5.0.0"
+ cids "^1.1.5"
+ err-code "^3.0.1"
+ hamt-sharding "^2.0.0"
+ ipfs-unixfs "^4.0.3"
+ ipld-dag-pb "^0.22.2"
+ it-all "^1.0.5"
+ it-batch "^1.0.8"
+ it-first "^1.0.6"
+ it-parallel-batch "^1.0.9"
+ merge-options "^3.0.4"
+ multihashing-async "^2.1.0"
+ rabin-wasm "^0.1.4"
+ uint8arrays "^2.1.2"
+
+ipfs-unixfs@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/ipfs-unixfs/-/ipfs-unixfs-4.0.3.tgz#7c43e5726052ade4317245358ac541ef3d63d94e"
+ integrity sha512-hzJ3X4vlKT8FQ3Xc4M1szaFVjsc1ZydN+E4VQ91aXxfpjFn9G2wsMo1EFdAXNq/BUnN5dgqIOMP5zRYr3DTsAw==
+ dependencies:
+ err-code "^3.0.1"
+ protobufjs "^6.10.2"
+
+ipld-dag-pb@^0.22.2:
+ version "0.22.3"
+ resolved "https://registry.yarnpkg.com/ipld-dag-pb/-/ipld-dag-pb-0.22.3.tgz#6d5af28b5752236a5cb0e0a1888c87dd733b55cd"
+ integrity sha512-dfG5C5OVAR4FEP7Al2CrHWvAyIM7UhAQrjnOYOIxXGQz5NlEj6wGX0XQf6Ru6or1na6upvV3NQfstapQG8X2rg==
+ dependencies:
+ cids "^1.0.0"
+ interface-ipld-format "^1.0.0"
+ multicodec "^3.0.1"
+ multihashing-async "^2.0.0"
+ protobufjs "^6.10.2"
+ stable "^0.1.8"
+ uint8arrays "^2.0.5"
+
is-arguments@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
- integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
+ integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^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 sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+ 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"
@@ -4134,45 +4875,73 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
-is-buffer@~2.0.3:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
- integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
+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-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
- integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==
+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-date-object@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
- integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
+is-buffer@~1.1.6:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+ integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-is-directory@^0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
- integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
+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:
+ 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:
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
+ integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
+ dependencies:
+ has "^1.0.3"
+
+is-core-module@^2.5.0:
+ version "2.15.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.0.tgz#71c72ec5442ace7e76b306e9d48db361f22699ea"
+ integrity sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==
+ dependencies:
+ hasown "^2.0.2"
+
+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-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
- integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
-
-is-finite@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3"
- integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==
+ integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
-is-fn@^1.0.0:
+is-fullwidth-code-point@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c"
- integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+ integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
+ dependencies:
+ number-is-nan "^1.0.0"
is-fullwidth-code-point@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
- integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
+ integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
@@ -4184,160 +4953,190 @@ is-function@^1.0.1:
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08"
integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==
-is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
- integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
+is-generator-function@^1.0.7:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
+ integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+ 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 sha1-fY035q135dEnFIkTxXPggtd39VQ=
+ integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==
-is-map@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1"
- integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==
+is-lower-case@^1.1.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393"
+ integrity sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==
+ dependencies:
+ lower-case "^1.1.0"
-is-natural-number@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
- integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=
+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-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
- integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
-
is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
- integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
+ integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==
-is-regex@^1.0.4, is-regex@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
- integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==
- dependencies:
- has-symbols "^1.0.1"
+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.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
- integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
+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:
- has "^1.0.3"
-
-is-retry-allowed@^1.0.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
- integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
-
-is-set@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
- integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
-is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
- integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+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.0"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
- integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
+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-string@^1.0.4, is-string@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
- integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
+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-symbol@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
- integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==
+is-typed-array@^1.1.10, is-typed-array@^1.1.3, 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:
- has-symbols "^1.0.1"
+ available-typed-arrays "^1.0.5"
+ call-bind "^1.0.2"
+ for-each "^0.3.3"
+ gopd "^1.0.1"
+ has-tostringtag "^1.0.0"
is-typedarray@^1.0.0, is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
- integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+ integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
-isarray@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
- integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
+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==
-isarray@^1.0.0, isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
+is-upper-case@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f"
+ integrity sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==
+ dependencies:
+ upper-case "^1.1.0"
+
+is-utf8@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+ integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==
+
+is-weakref@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
+ integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
+ dependencies:
+ call-bind "^1.0.2"
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 sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+ integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
- integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+ integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
-isurl@^1.0.0-alpha5:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
- integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
- dependencies:
- has-to-string-tag-x "^1.2.0"
- is-object "^1.0.1"
+it-all@^1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/it-all/-/it-all-1.0.6.tgz#852557355367606295c4c3b7eff0136f07749335"
+ integrity sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==
-iterate-iterator@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6"
- integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==
+it-batch@^1.0.8, it-batch@^1.0.9:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/it-batch/-/it-batch-1.0.9.tgz#7e95aaacb3f9b1b8ca6c8b8367892171d6a5b37f"
+ integrity sha512-7Q7HXewMhNFltTsAMdSz6luNhyhkhEtGGbYek/8Xb/GiqYMtwUmopE1ocPSiJKKp3rM4Dt045sNFoUu+KZGNyA==
-iterate-value@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57"
- integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==
+it-first@^1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/it-first/-/it-first-1.0.7.tgz#a4bef40da8be21667f7d23e44dae652f5ccd7ab1"
+ integrity sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g==
+
+it-parallel-batch@^1.0.9:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/it-parallel-batch/-/it-parallel-batch-1.0.11.tgz#f889b4e1c7a62ef24111dbafbaaa010b33d00f69"
+ integrity sha512-UWsWHv/kqBpMRmyZJzlmZeoAMA0F3SZr08FBdbhtbe+MtoEBgr/ZUAKrnenhXCBrsopy76QjRH2K/V8kNdupbQ==
dependencies:
- es-get-iterator "^1.0.2"
- iterate-iterator "^1.0.1"
+ it-batch "^1.0.9"
+
+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.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 sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=
+ 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-tokens@^3.0.0 || ^4.0.0", js-tokens@^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"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-js-tokens@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
- integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
-
js-yaml@3.13.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
@@ -4346,196 +5145,137 @@ js-yaml@3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
-js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1:
- version "3.14.0"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
- integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
+js-yaml@3.x, js-yaml@^3.13.1:
+ version "3.14.1"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
+ integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
+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"
+
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
- integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
-
-jsesc@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
- integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s=
+ integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
-jsesc@~0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
- integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
-
-json-bigint@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1"
- integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==
- dependencies:
- bignumber.js "^9.0.0"
-
-json-buffer@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
- integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
+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-better-errors@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
- integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
-
-json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0:
- version "3.8.0"
- resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9"
- integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==
- dependencies:
- async "^2.0.1"
- babel-preset-env "^1.7.0"
- babelify "^7.3.0"
- json-rpc-error "^2.0.0"
- promise-to-callback "^1.0.0"
- safe-event-emitter "^1.0.1"
-
-json-rpc-engine@^5.1.3:
- version "5.1.8"
- resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.1.8.tgz#5ba0147ce571899bbaa7133ffbc05317c34a3c7f"
- integrity sha512-vTBSDEPJV1fPAsbm2g5sEuPjsgLdiab2f1CTn2PyRr8nxggUpA996PDlNQDsM0gnrA99F8KIBLq2nIKrOFl1Mg==
- dependencies:
- async "^2.0.1"
- eth-json-rpc-errors "^2.0.1"
- promise-to-callback "^1.0.0"
- safe-event-emitter "^1.0.1"
-
-json-rpc-error@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02"
- integrity sha1-p6+cICg4tekFxyUOVH8a/3cligI=
+json-diff@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/json-diff/-/json-diff-0.5.2.tgz#e0bc9e434cd2c4c6354487835e01bf3fed335cda"
+ integrity sha512-N7oapTQdD4rLMUtA7d1HATCPY/BpHuSNL1mhvIuoS0u5NideDvyR+gB/ntXB7ejFz/LM0XzPLNUJQcC68n5sBw==
dependencies:
- inherits "^2.0.1"
+ cli-color "~0.1.6"
+ difflib "~0.2.1"
+ dreamopt "~0.6.0"
-json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8"
- integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg=
+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@0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
- integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
+json-schema-traverse@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
+ integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+
+json-schema@0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
+ integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-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 sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
-
-json-stable-stringify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
- integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=
- dependencies:
- jsonify "~0.0.0"
+ integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
- integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
+ integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
-json5@^0.5.1:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
- integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
-
-json5@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
- integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
+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"
jsonfile@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
- integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
+ 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 sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
+ integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
optionalDependencies:
graceful-fs "^4.1.6"
-jsonify@~0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
- integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
+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"
jsonschema@^1.2.4:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.6.tgz#52b0a8e9dc06bbae7295249d03e4b9faee8a0c0b"
- integrity sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA==
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab"
+ integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==
jsprim@^1.2.2:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
- integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
+ integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
- json-schema "0.2.3"
+ json-schema "0.4.0"
verror "1.10.0"
-jwa@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc"
- integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==
- dependencies:
- buffer-equal-constant-time "1.0.1"
- ecdsa-sig-formatter "1.0.11"
- safe-buffer "^5.0.1"
-
-jws@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4"
- integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==
- dependencies:
- jwa "^2.0.0"
- safe-buffer "^5.0.1"
-
-keccak@^1.0.2:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80"
- integrity sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==
- dependencies:
- bindings "^1.2.1"
- inherits "^2.0.3"
- nan "^2.2.1"
- safe-buffer "^5.1.0"
+just-extend@^6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-6.2.0.tgz#b816abfb3d67ee860482e7401564672558163947"
+ integrity sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==
-keccak@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff"
- integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==
+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@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
- integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
+keyv@^4.0.0:
+ version "4.5.3"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.3.tgz#00873d2b046df737963157bd04f294ca818c9c25"
+ integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==
dependencies:
- json-buffer "3.0.0"
+ json-buffer "3.0.1"
-kind-of@^6.0.2:
+kind-of@^6.0.2, kind-of@^6.0.3:
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==
@@ -4543,97 +5283,74 @@ kind-of@^6.0.2:
klaw@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
- integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk=
+ integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==
optionalDependencies:
graceful-fs "^4.1.9"
-lcid@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
- integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
- dependencies:
- invert-kv "^2.0.0"
-
-level-codec@~7.0.0:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7"
- integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==
-
-level-errors@^1.0.3:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d"
- integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w==
+lcid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
+ integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==
dependencies:
- errno "~0.1.1"
+ invert-kv "^1.0.0"
-level-errors@~1.0.3:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859"
- integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==
- dependencies:
- errno "~0.1.1"
+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-iterator-stream@~1.3.0:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed"
- integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=
+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:
- inherits "^2.0.1"
- level-errors "^1.0.3"
- readable-stream "^1.0.33"
- xtend "^4.0.0"
+ buffer "^6.0.3"
+ module-error "^1.0.1"
-level-ws@0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b"
- integrity sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=
+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:
- readable-stream "~1.0.15"
- xtend "~2.1.1"
+ browser-level "^1.0.1"
+ classic-level "^1.2.0"
-levelup@^1.2.1:
- version "1.3.9"
- resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab"
- integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==
+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:
- deferred-leveldown "~1.2.1"
- level-codec "~7.0.0"
- level-errors "~1.0.3"
- level-iterator-stream "~1.3.0"
- prr "~1.0.1"
- semver "~5.4.1"
- xtend "~4.0.0"
+ prelude-ls "^1.2.1"
+ type-check "~0.4.0"
-levn@^0.3.0, levn@~0.3.0:
+levn@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
- integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
+ integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==
dependencies:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-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==
-load-json-file@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
- integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=
+load-json-file@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
+ integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==
dependencies:
graceful-fs "^4.1.2"
parse-json "^2.2.0"
pify "^2.0.0"
- strip-bom "^3.0.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
- integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
+ integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==
dependencies:
p-locate "^2.0.0"
path-exists "^3.0.0"
@@ -4653,20 +5370,47 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
-lodash.flatmap@^4.5.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.assign@^4.0.3, lodash.assign@^4.0.6:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
+ integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==
+
+lodash.camelcase@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
+ integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
+
+lodash.get@^4.4.2:
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+ integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
+
+lodash.isequal@^4.5.0:
version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz#ef8cbf408f6e48268663345305c6acc0b778702e"
- integrity sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=
+ resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
+ integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
-lodash.toarray@^4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
- integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE=
+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.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4:
- version "4.17.19"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
- integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
+lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, 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@3.0.0:
version "3.0.0"
@@ -4675,23 +5419,55 @@ log-symbols@3.0.0:
dependencies:
chalk "^2.4.2"
-loose-envify@^1.0.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
- integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+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:
- js-tokens "^3.0.0 || ^4.0.0"
+ chalk "^4.1.0"
+ is-unicode-supported "^0.1.0"
-lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
- integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
+long@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
+ integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
+
+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"
+
+lower-case-first@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1"
+ integrity sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==
+ dependencies:
+ lower-case "^1.1.2"
+
+lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
+ integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==
lowercase-keys@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
+lowercase-keys@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2"
+ integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==
+
+lru-cache@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
+ 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"
@@ -4699,29 +5475,35 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
-ltgt@~2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5"
- integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=
-
-make-dir@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
- integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
- dependencies:
- pify "^3.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==
-map-age-cleaner@^0.1.1:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
- integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
- dependencies:
- p-defer "^1.0.0"
+map-obj@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
+ integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==
+
+map-obj@^4.0.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a"
+ integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
+
+markdown-table@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60"
+ integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==
+
+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"
@@ -4732,149 +5514,179 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
+md5@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
+ integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
+ dependencies:
+ charenc "0.0.2"
+ crypt "0.0.2"
+ is-buffer "~1.1.6"
+
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
- integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
-
-mem@^4.0.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
- integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
- dependencies:
- map-age-cleaner "^0.1.1"
- mimic-fn "^2.0.0"
- p-is-promise "^2.0.0"
+ integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
-memdown@^1.0.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215"
- integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=
+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-leveldown "~2.7.1"
+ abstract-level "^1.0.0"
functional-red-black-tree "^1.0.1"
- immediate "^3.2.3"
- inherits "~2.0.1"
- ltgt "~2.2.0"
- safe-buffer "~5.1.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 sha1-htcJCzDORV1j+64S3aUaR93K+bI=
+ integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==
+
+meow@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-9.0.0.tgz#cd9510bc5cac9dee7d03c73ee1f9ad959f4ea364"
+ integrity sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==
+ dependencies:
+ "@types/minimist" "^1.2.0"
+ camelcase-keys "^6.2.2"
+ decamelize "^1.2.0"
+ decamelize-keys "^1.1.0"
+ hard-rejection "^2.1.0"
+ minimist-options "4.1.0"
+ normalize-package-data "^3.0.0"
+ read-pkg-up "^7.0.1"
+ redent "^3.0.0"
+ trim-newlines "^3.0.0"
+ type-fest "^0.18.0"
+ yargs-parser "^20.2.3"
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
- integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
+ integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
+
+merge-options@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7"
+ integrity sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==
+ dependencies:
+ is-plain-obj "^2.1.0"
merge2@^1.2.3, merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
-merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a"
- integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==
- dependencies:
- async "^1.4.2"
- ethereumjs-util "^5.0.0"
- level-ws "0.0.0"
- levelup "^1.2.1"
- memdown "^1.0.0"
- readable-stream "^2.0.0"
- rlp "^2.0.0"
- semaphore ">=1.0.1"
-
methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
- integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
+ integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
-micromatch@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
- integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
- dependencies:
- braces "^3.0.1"
- picomatch "^2.0.5"
+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==
-miller-rabin@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
- integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
+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:
- bn.js "^4.0.0"
- brorand "^1.0.1"
+ braces "^3.0.2"
+ picomatch "^2.3.1"
-mime-db@1.44.0:
- version "1.44.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
- integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
+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, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24:
- version "2.1.27"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
- integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
+mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
+ version "2.1.35"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
- mime-db "1.44.0"
+ mime-db "1.52.0"
mime@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
-mime@^2.2.0:
- version "2.4.6"
- resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1"
- integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==
-
-mimic-fn@^1.0.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
- integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
-
-mimic-fn@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
- integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
-
-mimic-response@^1.0.0, mimic-response@^1.0.1:
+mimic-response@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
+mimic-response@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
+ integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
+
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
- integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
+ integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==
dependencies:
dom-walk "^0.1.0"
+min-indent@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
+ integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
+
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.0, minimalistic-crypto-utils@^1.0.1:
+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 sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
+ integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
+
+"minimatch@2 || 3", 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@2 || 3", minimatch@3.0.4, minimatch@^3.0.4:
+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"
-minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+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@^5.0.1:
+ 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"
+
+minimist-options@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
+ integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==
+ dependencies:
+ arrify "^1.0.1"
+ is-plain-obj "^1.1.0"
+ kind-of "^6.0.3"
-minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
+minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
+ integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
+
+minipass@^2.6.0, minipass@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
@@ -4882,7 +5694,7 @@ minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
safe-buffer "^5.1.2"
yallist "^3.0.0"
-minizlib@^1.2.1:
+minizlib@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
@@ -4892,73 +5704,173 @@ minizlib@^1.2.1:
mkdirp-promise@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1"
- integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=
+ integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==
dependencies:
mkdirp "*"
-mkdirp@*:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
- integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+mkdirp@*, mkdirp@^3.0.0:
+ 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.0, mkdirp@^0.5.1:
+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"
-mocha@8.0.1:
- version "8.0.1"
- resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.0.1.tgz#fe01f0530362df271aa8f99510447bc38b88d8ed"
- integrity sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==
+mkdirp@0.5.x, mkdirp@^0.5.5:
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
+ integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
+ 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==
+
+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-junit-reporter@2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-2.2.1.tgz#739f5595d0f051d07af9d74e32c416e13a41cde5"
+ integrity sha512-iDn2tlKHn8Vh8o4nCzcUVW4q7iXp7cC4EB78N0cDHIobLymyHNwe0XG8HEHHjc3hJlXm0Vy6zcrxaIhnI2fWmw==
+ dependencies:
+ debug "^4.3.4"
+ md5 "^2.3.0"
+ mkdirp "^3.0.0"
+ strip-ansi "^6.0.1"
+ xml "^1.0.1"
+
+mocha-multi-reporters@1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/mocha-multi-reporters/-/mocha-multi-reporters-1.5.1.tgz#c73486bed5519e1d59c9ce39ac7a9792600e5676"
+ integrity sha512-Yb4QJOaGLIcmB0VY7Wif5AjvLMUFAdV57D2TWEva1Y0kU/3LjKpeRVmlMIfuO1SVbauve459kgtIizADqxMWPg==
+ dependencies:
+ debug "^4.1.1"
+ lodash "^4.17.15"
+
+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@^10.2.0:
+ version "10.3.0"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9"
+ integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==
dependencies:
ansi-colors "4.1.1"
browser-stdout "1.3.1"
- chokidar "3.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 "8.1.0"
+ he "1.2.0"
+ js-yaml "4.1.0"
+ log-symbols "4.1.0"
+ minimatch "5.0.1"
+ ms "2.1.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@^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 "4.0.2"
+ diff "3.5.0"
escape-string-regexp "1.0.5"
- find-up "4.1.0"
- glob "7.1.6"
+ 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"
- ms "2.1.2"
+ mkdirp "0.5.5"
+ ms "2.1.1"
+ node-environment-flags "1.0.6"
object.assign "4.1.0"
- promise.allsettled "1.0.2"
- serialize-javascript "3.0.0"
- strip-json-comments "3.0.1"
- supports-color "7.1.0"
- which "2.0.2"
+ strip-json-comments "2.0.1"
+ supports-color "6.0.0"
+ which "1.3.1"
wide-align "1.1.3"
- workerpool "6.0.0"
yargs "13.3.2"
yargs-parser "13.1.2"
yargs-unparser "1.6.0"
mock-fs@^4.1.0:
- version "4.12.0"
- resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.12.0.tgz#a5d50b12d2d75e5bec9dac3b67ffe3c41d31ade4"
- integrity sha512-/P/HtrlvBxY4o/PzXY9cCNBrdylDNxg7gnrv2sMNxj+UJ2m8jSpl0/A6fuJeNAWr99ZvGWH8XCbE0vmnM5KupQ==
+ version "4.14.0"
+ resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18"
+ integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==
+
+module-error@^1.0.1, module-error@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86"
+ integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+ 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, ms@^2.1.1:
+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==
+
multibase@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b"
@@ -4967,6 +5879,13 @@ multibase@^0.7.0:
base-x "^3.0.8"
buffer "^5.5.0"
+multibase@^4.0.1:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.6.tgz#6e624341483d6123ca1ede956208cb821b440559"
+ integrity sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==
+ dependencies:
+ "@multiformats/base-x" "^4.0.1"
+
multibase@~0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b"
@@ -4990,6 +5909,19 @@ multicodec@^1.0.0:
buffer "^5.6.0"
varint "^5.0.0"
+multicodec@^3.0.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-3.2.1.tgz#82de3254a0fb163a107c1aab324f2a91ef51efb2"
+ integrity sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw==
+ dependencies:
+ uint8arrays "^3.0.0"
+ varint "^6.0.0"
+
+multiformats@^9.4.2:
+ version "9.9.0"
+ resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37"
+ integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==
+
multihashes@^0.4.15, multihashes@~0.4.15:
version "0.4.21"
resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5"
@@ -4999,45 +5931,89 @@ multihashes@^0.4.15, multihashes@~0.4.15:
multibase "^0.7.0"
varint "^5.0.0"
-mute-stream@0.0.7:
- version "0.0.7"
- resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
- integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
+multihashes@^4.0.1, multihashes@^4.0.2:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-4.0.3.tgz#426610539cd2551edbf533adeac4c06b3b90fb05"
+ integrity sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA==
+ dependencies:
+ multibase "^4.0.1"
+ uint8arrays "^3.0.0"
+ varint "^5.0.2"
+
+multihashing-async@^2.0.0, multihashing-async@^2.1.0:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/multihashing-async/-/multihashing-async-2.1.4.tgz#26dce2ec7a40f0e7f9e732fc23ca5f564d693843"
+ integrity sha512-sB1MiQXPSBTNRVSJc2zM157PXgDtud2nMFUEIvBrsq5Wv96sUclMRK/ecjoP1T/W61UJBqt4tCTwMkUpt2Gbzg==
+ dependencies:
+ blakejs "^1.1.0"
+ err-code "^3.0.0"
+ js-sha3 "^0.8.0"
+ multihashes "^4.0.1"
+ murmurhash3js-revisited "^3.0.0"
+ uint8arrays "^3.0.0"
+
+murmurhash3js-revisited@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz#6bd36e25de8f73394222adc6e41fa3fac08a5869"
+ integrity sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==
-nan@^2.14.0, nan@^2.2.1:
- version "2.14.1"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
- integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
+nano-base32@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef"
+ integrity sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==
nano-json-stream-parser@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f"
- integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=
+ integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==
+
+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.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"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
- integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
+ integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
-negotiator@0.6.2:
- version "0.6.2"
- resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
- integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
+negotiator@0.6.3:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
+ integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
neo-async@^2.6.0:
version "2.6.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
-next-tick@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
- integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
+next-tick@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
+ integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
-nice-try@^1.0.4:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
- integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
+nise@^6.1.1:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/nise/-/nise-6.1.1.tgz#78ea93cc49be122e44cb7c8fdf597b0e8778b64a"
+ integrity sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==
+ dependencies:
+ "@sinonjs/commons" "^3.0.1"
+ "@sinonjs/fake-timers" "^13.0.1"
+ "@sinonjs/text-encoding" "^0.7.3"
+ just-extend "^6.2.0"
+ path-to-regexp "^8.1.0"
+
+no-case@^2.2.0, no-case@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
+ integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
+ dependencies:
+ lower-case "^1.1.1"
node-addon-api@^2.0.0:
version "2.0.2"
@@ -5045,48 +6021,57 @@ node-addon-api@^2.0.0:
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==
node-emoji@^1.10.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da"
- integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c"
+ integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==
dependencies:
- lodash.toarray "^4.4.0"
+ lodash "^4.17.21"
-node-fetch@2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5"
- integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=
+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.3.0:
- version "2.6.0"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
- integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
+node-fetch@^2.6.1:
+ 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"
-node-fetch@~1.7.1:
- version "1.7.3"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
- integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
+node-fetch@^2.6.12:
+ version "2.6.12"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba"
+ integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==
dependencies:
- encoding "^0.1.11"
- is-stream "^1.0.1"
+ whatwg-url "^5.0.0"
-node-forge@^0.9.0:
- version "0.9.1"
- resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.1.tgz#775368e6846558ab6676858a4d8c6e8d16c677b5"
- integrity sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==
+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==
-node-gyp-build@^4.2.0:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739"
- integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==
+nofilter@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e"
+ integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==
+
+nofilter@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66"
+ integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==
nopt@3.x:
version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
- integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k=
+ integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==
dependencies:
abbrev "1"
-normalize-package-data@^2.3.2:
+normalize-package-data@^2.3.2, normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
@@ -5096,27 +6081,42 @@ normalize-package-data@^2.3.2:
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
+normalize-package-data@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e"
+ integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==
+ dependencies:
+ hosted-git-info "^4.0.1"
+ is-core-module "^2.5.0"
+ semver "^7.3.4"
+ validate-npm-package-license "^3.0.1"
+
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-normalize-url@^4.1.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
- integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
+normalize-url@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
+ integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
-npm-run-path@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
- integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
+nth-check@^2.0.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
+ integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
- path-key "^2.0.0"
+ boolbase "^1.0.0"
+
+number-is-nan@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+ integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
number-to-bn@1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0"
- integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=
+ integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==
dependencies:
bn.js "4.11.6"
strip-hex-prefix "1.0.0"
@@ -5126,40 +6126,22 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
-object-assign@^4, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
+object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-object-inspect@^1.7.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
- integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==
-
-object-inspect@~1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
- integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
+ integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
-object-is@^1.0.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6"
- integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.5"
+object-inspect@^1.12.3, object-inspect@^1.9.0:
+ 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-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
+object-keys@^1.0.11, 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-keys@~0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336"
- integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=
-
-object.assign@4.1.0, object.assign@^4.1.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==
@@ -5169,45 +6151,63 @@ object.assign@4.1.0, object.assign@^4.1.0:
has-symbols "^1.0.0"
object-keys "^1.0.11"
-object.values@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e"
- integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==
+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:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- function-bind "^1.1.1"
- has "^1.0.3"
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ has-symbols "^1.0.3"
+ object-keys "^1.1.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==
+ dependencies:
+ array.prototype.reduce "^1.0.5"
+ call-bind "^1.0.2"
+ define-properties "^1.2.0"
+ es-abstract "^1.21.2"
+ safe-array-concat "^1.0.0"
+
+object.values@^1.1.6:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d"
+ integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
-oboe@2.1.4:
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6"
- integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=
+obliterator@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816"
+ integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==
+
+oboe@2.1.5:
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd"
+ integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==
dependencies:
http-https "^1.0.0"
-on-finished@~2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
- integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
+on-finished@2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
+ integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
dependencies:
ee-first "1.1.1"
once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+ integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
-onetime@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
- integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=
- dependencies:
- mimic-fn "^1.0.0"
-
-optionator@^0.8.1, optionator@^0.8.2:
+optionator@^0.8.1:
version "0.8.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
@@ -5220,65 +6220,43 @@ optionator@^0.8.1, optionator@^0.8.2:
word-wrap "~1.2.3"
optionator@^0.9.1:
- version "0.9.1"
- resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
- integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
+ 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"
- word-wrap "^1.2.3"
-original-require@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/original-require/-/original-require-1.0.1.tgz#0f130471584cd33511c5ec38c8d59213f9ac5e20"
- integrity sha1-DxMEcVhM0zURxew4yNWSE/msXiA=
-
-os-homedir@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
- integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
+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-locale@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
- integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
+os-locale@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
+ integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==
dependencies:
- execa "^1.0.0"
- lcid "^2.0.0"
- mem "^4.0.0"
+ lcid "^1.0.0"
-os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
+os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
- integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-
-p-cancelable@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
- integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==
+ integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
-p-cancelable@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
- integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
-
-p-defer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
- integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
-
-p-finally@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
- integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
+p-cancelable@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
+ integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
-p-is-promise@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
- integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
+p-cancelable@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050"
+ integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==
p-limit@^1.1.0:
version "1.3.0"
@@ -5294,10 +6272,17 @@ p-limit@^2.0.0, p-limit@^2.2.0:
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"
+ 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 sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
+ integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==
dependencies:
p-limit "^1.1.0"
@@ -5315,23 +6300,42 @@ p-locate@^4.1.0:
dependencies:
p-limit "^2.2.0"
-p-timeout@^1.1.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
- integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=
+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:
- p-finally "^1.0.0"
+ 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 sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
+ 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==
+pako@^1.0.4:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
+ integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
+
+param-case@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
+ integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==
+ dependencies:
+ no-case "^2.2.0"
+
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@@ -5339,17 +6343,10 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
-parse-asn1@^5.0.0, parse-asn1@^5.1.5:
- version "5.1.5"
- resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e"
- integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==
- dependencies:
- asn1.js "^4.0.0"
- browserify-aes "^1.0.0"
- create-hash "^1.1.0"
- evp_bytestokey "^1.0.0"
- pbkdf2 "^3.0.3"
- safe-buffer "^5.1.1"
+parse-cache-control@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e"
+ integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==
parse-code-context@^1.0.0:
version "1.0.0"
@@ -5357,91 +6354,127 @@ parse-code-context@^1.0.0:
integrity sha512-OZQaqKaQnR21iqhlnPfVisFjBWjhnMl5J9MgbP8xC+EwoVqbXrq78lp+9Zb3ahmLzrIX5Us/qbvBnaS3hkH6OA==
parse-headers@^2.0.0:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515"
- integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
+ integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==
parse-json@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
- integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
+ integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==
dependencies:
error-ex "^1.2.0"
-parse-json@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
- integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
+parse-json@^5.0.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-better-errors "^1.0.1"
+ json-parse-even-better-errors "^2.3.0"
+ lines-and-columns "^1.1.6"
+
+parse5-htmlparser2-tree-adapter@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1"
+ integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==
+ dependencies:
+ domhandler "^5.0.2"
+ parse5 "^7.0.0"
+
+parse5@^7.0.0:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"
+ integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==
+ dependencies:
+ entities "^4.4.0"
parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
+pascal-case@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e"
+ integrity sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==
+ dependencies:
+ camel-case "^3.0.0"
+ upper-case-first "^1.1.0"
+
+path-case@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5"
+ integrity sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==
+ dependencies:
+ no-case "^2.2.0"
+
+path-exists@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
+ integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==
+ dependencies:
+ pinkie-promise "^2.0.0"
+
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
- integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
+ 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, path-is-absolute@^1.0.1:
+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 sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-
-path-is-inside@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
- integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
-
-path-key@^2.0.0, path-key@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
- integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
+ integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
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-parse@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
- integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
+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-to-regexp@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
- integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
+ integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
-path-type@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
- integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=
+path-to-regexp@^8.1.0:
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.2.0.tgz#73990cc29e57a3ff2a0d914095156df5db79e8b4"
+ integrity sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==
+
+path-type@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
+ integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==
dependencies:
+ graceful-fs "^4.1.2"
pify "^2.0.0"
+ pinkie-promise "^2.0.0"
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-pathval@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0"
- integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA=
+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, pbkdf2@^3.0.3:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94"
- integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==
+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"
@@ -5449,30 +6482,20 @@ pbkdf2@^3.0.17, pbkdf2@^3.0.3:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-pend@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
- integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
-
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
- integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+ integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
-picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
- integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-pify@^2.0.0, pify@^2.3.0:
+pify@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
- integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
-
-pify@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
- integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
+ integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
pify@^4.0.1:
version "4.0.1"
@@ -5482,26 +6505,19 @@ pify@^4.0.1:
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
- integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
+ integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==
dependencies:
pinkie "^2.0.0"
pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
- integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
-
-pkg-dir@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
- integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=
- dependencies:
- find-up "^2.1.0"
+ integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==
-precond@0.2:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac"
- integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=
+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"
@@ -5511,17 +6527,7 @@ prelude-ls@^1.2.1:
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
- integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
-
-prepend-http@^1.0.1:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
- integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
-
-prepend-http@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
- integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
+ integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
prettier-linter-helpers@^1.0.0:
version "1.0.0"
@@ -5544,84 +6550,69 @@ prettier-plugin-solidity@1.0.0-alpha.54:
semver "^7.3.2"
string-width "^4.2.0"
-prettier@2.0.5, prettier@^2.0.5:
+prettier@2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==
-prettier@^1.14.2, prettier@^1.14.3:
- version "1.19.1"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
- integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
-
-private@^0.1.6, private@^0.1.8:
- version "0.1.8"
- resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
- integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
+prettier@^2.0.5, prettier@^2.3.1, 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==
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==
-process@~0.5.1:
- version "0.5.2"
- resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
- integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=
+process@^0.11.10:
+ version "0.11.10"
+ resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
+ integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
progress@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-promise-to-callback@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7"
- integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=
- dependencies:
- is-fn "^1.0.0"
- set-immediate-shim "^1.0.1"
-
-promise.allsettled@1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.2.tgz#d66f78fbb600e83e863d893e98b3d4376a9c47c9"
- integrity sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==
- dependencies:
- array.prototype.map "^1.0.1"
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- function-bind "^1.1.1"
- iterate-value "^1.0.0"
-
-proxy-addr@~2.0.5:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
- integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==
+promise@^8.0.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a"
+ integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==
+ dependencies:
+ asap "~2.0.6"
+
+protobufjs@^6.10.2:
+ version "6.11.4"
+ resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa"
+ integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==
+ dependencies:
+ "@protobufjs/aspromise" "^1.1.2"
+ "@protobufjs/base64" "^1.1.2"
+ "@protobufjs/codegen" "^2.0.4"
+ "@protobufjs/eventemitter" "^1.1.0"
+ "@protobufjs/fetch" "^1.1.0"
+ "@protobufjs/float" "^1.0.2"
+ "@protobufjs/inquire" "^1.1.0"
+ "@protobufjs/path" "^1.1.2"
+ "@protobufjs/pool" "^1.1.0"
+ "@protobufjs/utf8" "^1.1.0"
+ "@types/long" "^4.0.1"
+ "@types/node" ">=13.7.0"
+ long "^4.0.0"
+
+proxy-addr@~2.0.7:
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
+ integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
dependencies:
- forwarded "~0.1.2"
+ forwarded "0.2.0"
ipaddr.js "1.9.1"
-prr@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
- integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
-
psl@^1.1.28:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
- integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
-
-public-encrypt@^4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
- integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
- dependencies:
- bn.js "^4.1.0"
- browserify-rsa "^4.0.0"
- create-hash "^1.1.0"
- parse-asn1 "^5.0.0"
- randombytes "^2.0.1"
- safe-buffer "^5.1.2"
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
+ integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
pump@^3.0.0:
version "3.0.0"
@@ -5634,32 +6625,46 @@ pump@^3.0.0:
punycode@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
- integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=
+ integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==
-punycode@^2.1.0, punycode@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
- integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+punycode@^2.1.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
+ integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
+
+punycode@^2.1.1:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
+ integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
+
+pure-rand@^5.0.1:
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-5.0.5.tgz#bda2a7f6a1fc0f284d78d78ca5902f26f2ad35cf"
+ integrity sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==
-q@^1.5.1:
+q@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
- integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
+ integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==
-qs@6.7.0:
- version "6.7.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
- integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
+qs@6.11.0:
+ version "6.11.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
+ integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
+ dependencies:
+ side-channel "^1.0.4"
-qs@^6.7.0:
- version "6.9.4"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
- integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
+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==
+ dependencies:
+ side-channel "^1.0.4"
qs@~6.5.2:
- version "6.5.2"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
- integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
+ version "6.5.3"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
+ integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
query-string@^5.0.1:
version "5.1.1"
@@ -5670,72 +6675,105 @@ query-string@^5.0.1:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
-randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0:
+queue-microtask@^1.2.2, queue-microtask@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
+ integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+quick-lru@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
+ integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
+
+quick-lru@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
+ integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
+
+rabin-wasm@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/rabin-wasm/-/rabin-wasm-0.1.5.tgz#5b625ca007d6a2cbc1456c78ae71d550addbc9c9"
+ integrity sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==
+ dependencies:
+ "@assemblyscript/loader" "^0.9.4"
+ bl "^5.0.0"
+ debug "^4.3.1"
+ minimist "^1.2.5"
+ node-fetch "^2.6.1"
+ readable-stream "^3.6.0"
+
+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"
-randomfill@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
- integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
- dependencies:
- randombytes "^2.0.5"
- safe-buffer "^5.1.0"
-
-randomhex@0.1.5:
- version "0.1.5"
- resolved "https://registry.yarnpkg.com/randomhex/-/randomhex-0.1.5.tgz#baceef982329091400f2a2912c6cd02f1094f585"
- integrity sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=
-
range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
-raw-body@2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
- integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
+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==
dependencies:
- bytes "3.1.0"
- http-errors "1.7.2"
+ bytes "3.1.2"
+ http-errors "2.0.0"
iconv-lite "0.4.24"
unpipe "1.0.0"
-read-pkg-up@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
- integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=
+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:
- find-up "^2.0.0"
- read-pkg "^2.0.0"
+ bytes "3.1.2"
+ http-errors "2.0.0"
+ iconv-lite "0.4.24"
+ unpipe "1.0.0"
-read-pkg@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
- integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=
+read-pkg-up@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
+ integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==
+ dependencies:
+ find-up "^1.0.0"
+ read-pkg "^1.0.0"
+
+read-pkg-up@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
+ integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==
dependencies:
- load-json-file "^2.0.0"
+ find-up "^4.1.0"
+ read-pkg "^5.2.0"
+ type-fest "^0.8.1"
+
+read-pkg@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
+ integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==
+ dependencies:
+ load-json-file "^1.0.0"
normalize-package-data "^2.3.2"
- path-type "^2.0.0"
+ path-type "^1.0.0"
-readable-stream@^1.0.33:
- version "1.1.14"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
- integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
+read-pkg@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
+ integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.1"
- isarray "0.0.1"
- string_decoder "~0.10.x"
+ "@types/normalize-package-data" "^2.4.0"
+ normalize-package-data "^2.5.0"
+ parse-json "^5.0.0"
+ type-fest "^0.6.0"
-readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.5, 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.2.2:
+ 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"
@@ -5745,117 +6783,106 @@ readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@^2.2.9, readable
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-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.4.0, readable-stream@^3.6.0:
+ 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:
- version "1.0.34"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
- integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
+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:
- core-util-is "~1.0.0"
- inherits "~2.0.1"
- isarray "0.0.1"
- string_decoder "~0.10.x"
+ picomatch "^2.0.4"
-readdirp@~3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17"
- integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==
+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.0.7"
+ picomatch "^2.2.1"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
- integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
+ integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==
dependencies:
resolve "^1.1.6"
recursive-readdir@^2.2.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f"
- integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372"
+ integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==
dependencies:
- minimatch "3.0.4"
-
-regenerate@^1.2.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f"
- integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==
+ minimatch "^3.0.5"
-regenerator-runtime@^0.11.0:
- version "0.11.1"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
- integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
+redent@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"
+ integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==
+ dependencies:
+ indent-string "^4.0.0"
+ strip-indent "^3.0.0"
-regenerator-runtime@^0.13.4:
- version "0.13.5"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
- integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
+reduce-flatten@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27"
+ integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==
-regenerator-transform@^0.10.0:
- version "0.10.1"
- resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
- integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==
- dependencies:
- babel-runtime "^6.18.0"
- babel-types "^6.19.0"
- private "^0.1.6"
+regenerator-runtime@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
+ integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
-regexp.prototype.flags@^1.2.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
- integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==
+regexp.prototype.flags@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb"
+ integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==
dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
-
-regexpp@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
- integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
+ call-bind "^1.0.2"
+ define-properties "^1.2.0"
+ functions-have-names "^1.2.3"
regexpp@^3.0.0, regexpp@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
- integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
+ integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
-regexpu-core@^2.0.0:
+req-cwd@^2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240"
- integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=
+ resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc"
+ integrity sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==
dependencies:
- regenerate "^1.2.1"
- regjsgen "^0.2.0"
- regjsparser "^0.1.4"
+ req-from "^2.0.0"
-regjsgen@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
- integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=
+req-from@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/req-from/-/req-from-2.0.0.tgz#d74188e47f93796f4aa71df6ee35ae689f3e0e70"
+ integrity sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==
+ dependencies:
+ resolve-from "^3.0.0"
-regjsparser@^0.1.4:
- version "0.1.5"
- resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
- integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=
+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:
- jsesc "~0.5.0"
+ lodash "^4.17.19"
-repeating@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
- integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=
+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:
- is-finite "^1.0.0"
+ 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.79.0, request@^2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -5884,22 +6911,37 @@ request@^2.79.0, request@^2.85.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 sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
+ integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+
+require-from-string@^1.1.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418"
+ integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==
-require-from-string@^2.0.0:
+require-from-string@^2.0.0, require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
+require-main-filename@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
+ integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==
+
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, resolve-alpn@^1.2.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
+ integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==
+
resolve-from@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
- integrity sha1-six699nWiBvItuZTM17rywoYh0g=
+ integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==
resolve-from@^4.0.0:
version "4.0.0"
@@ -5909,49 +6951,45 @@ resolve-from@^4.0.0:
resolve@1.1.x:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
- integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
+ integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==
-resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.8.1, resolve@~1.17.0:
+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"
-responselike@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
- integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
+resolve@^1.1.6, resolve@^1.10.1, resolve@^1.22.1:
+ version "1.22.2"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
+ integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
dependencies:
- lowercase-keys "^1.0.0"
+ is-core-module "^2.11.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
-restore-cursor@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
- integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368=
+resolve@^1.10.0:
+ version "1.22.4"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34"
+ integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==
dependencies:
- onetime "^2.0.0"
- signal-exit "^3.0.2"
+ is-core-module "^2.13.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
-resumer@~0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759"
- integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=
+responselike@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc"
+ integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==
dependencies:
- through "~2.3.4"
+ lowercase-keys "^2.0.0"
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.6.3:
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
- integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
- dependencies:
- glob "^7.1.3"
-
rimraf@^2.2.8:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@@ -5959,7 +6997,19 @@ rimraf@^2.2.8:
dependencies:
glob "^7.1.3"
-ripemd160@^2.0.0, ripemd160@^2.0.1:
+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-min@0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62"
+ integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==
+
+ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
@@ -5967,61 +7017,70 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^3.0.0"
inherits "^2.0.1"
-rlp@^2.0.0, rlp@^2.2.3, rlp@^2.2.4:
- version "2.2.6"
- resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c"
- integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==
+rlp@^2.2.3, rlp@^2.2.4:
+ 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 "^4.11.1"
+ bn.js "^5.2.0"
-run-async@^2.2.0:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
- integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
+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.1.9"
- resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
- integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
+ 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==
-rxjs@^6.4.0:
- version "6.6.0"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.0.tgz#af2901eedf02e3a83ffa7f886240ff9018bbec84"
- integrity sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==
+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:
- tslib "^1.9.0"
-
-safe-buffer@5.1.2, 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==
+ call-bind "^1.0.2"
+ get-intrinsic "^1.2.0"
+ has-symbols "^1.0.3"
+ isarray "^2.0.5"
-safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
+safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-safe-event-emitter@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af"
- integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==
+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:
- events "^3.0.0"
+ 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.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sc-istanbul@^0.4.5:
- version "0.4.5"
- resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.5.tgz#1896066484d55336cf2cdbcc7884dc79da50dc76"
- integrity sha512-7wR5EZFLsC4w0wSm9BUuCgW+OGKAU7PNlW5L0qwVPbh+Q1sfVn2fyzfMXYCm6rkNA5ipaCOt94nApcguQwF5Gg==
+ version "0.4.6"
+ resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839"
+ integrity sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==
dependencies:
abbrev "1.0.x"
async "1.x"
@@ -6038,133 +7097,92 @@ sc-istanbul@^0.4.5:
which "^1.1.1"
wordwrap "^1.0.0"
-scrypt-js@2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4"
- integrity sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=
-
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.0, scrypt-js@^3.0.1:
+scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312"
integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==
-"scrypt-shim@github:web3-js/scrypt-shim":
- version "0.1.0"
- resolved "https://codeload.github.com/web3-js/scrypt-shim/tar.gz/aafdadda13e660e25e1c525d1f5b2443f5eb1ebb"
- dependencies:
- scryptsy "^2.1.0"
- semver "^6.3.0"
-
-scryptsy@2.1.0, scryptsy@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790"
- integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==
-
-scryptsy@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163"
- integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM=
- dependencies:
- pbkdf2 "^3.0.3"
-
-secp256k1@^3.0.1:
- version "3.8.0"
- resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d"
- integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==
- dependencies:
- bindings "^1.5.0"
- bip66 "^1.1.5"
- bn.js "^4.11.8"
- create-hash "^1.2.0"
- drbg.js "^1.0.1"
- elliptic "^6.5.2"
- nan "^2.14.0"
- safe-buffer "^5.1.2"
-
secp256k1@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1"
- integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==
+ 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.2"
+ elliptic "^6.5.4"
node-addon-api "^2.0.0"
node-gyp-build "^4.2.0"
-seek-bzip@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc"
- integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=
- dependencies:
- commander "~2.8.1"
-
-semaphore@>=1.0.1, semaphore@^1.0.3:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
- integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==
-
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1:
- version "5.7.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
- integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
+"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, 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.2.0:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db"
- integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==
+semver@7.5.2:
+ version "7.5.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb"
+ integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==
+ dependencies:
+ lru-cache "^6.0.0"
semver@^6.1.0, 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@^7.2.1, semver@^7.3.2:
- version "7.3.2"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
- integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-semver@~5.4.1:
- version "5.4.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
- integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==
+semver@^7.2.1, semver@^7.3.2, semver@^7.3.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"
-send@0.17.1:
- version "0.17.1"
- resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
- integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==
+send@0.18.0:
+ version "0.18.0"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
+ integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
dependencies:
debug "2.6.9"
- depd "~1.1.2"
- destroy "~1.0.4"
+ depd "2.0.0"
+ destroy "1.2.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
- http-errors "~1.7.2"
+ http-errors "2.0.0"
mime "1.6.0"
- ms "2.1.1"
- on-finished "~2.3.0"
+ ms "2.1.3"
+ on-finished "2.4.1"
range-parser "~1.2.1"
- statuses "~1.5.0"
+ statuses "2.0.1"
-serialize-javascript@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.0.0.tgz#492e489a2d77b7b804ad391a5f5d97870952548e"
- integrity sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==
+sentence-case@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4"
+ integrity sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==
+ dependencies:
+ no-case "^2.2.0"
+ upper-case-first "^1.1.2"
-serve-static@1.14.1:
- version "1.14.1"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
- integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
+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"
+
+serve-static@1.15.0:
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
+ integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
dependencies:
encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.3"
- send "0.17.1"
+ send "0.18.0"
servify@^0.1.12:
version "0.1.12"
@@ -6180,27 +7198,22 @@ servify@^0.1.12:
set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
- integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
-
-set-immediate-shim@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
- integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=
+ integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
setimmediate@1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f"
- integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=
+ 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"
- integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
+ integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
-setprototypeof@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
- integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
+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"
@@ -6210,12 +7223,20 @@ sha.js@^2.4.0, sha.js@^2.4.8:
inherits "^2.0.1"
safe-buffer "^5.0.1"
-shebang-command@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
- integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
+sha1@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848"
+ integrity sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==
+ dependencies:
+ charenc ">= 0.0.1"
+ crypt ">= 0.0.1"
+
+sha3@^2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f"
+ integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==
dependencies:
- shebang-regex "^1.0.0"
+ buffer "6.0.3"
shebang-command@^2.0.0:
version "2.0.0"
@@ -6224,29 +7245,28 @@ shebang-command@^2.0.0:
dependencies:
shebang-regex "^3.0.0"
-shebang-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
- integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
-
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==
shelljs@^0.8.3:
- version "0.8.4"
- resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
- integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==
+ version "0.8.5"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
+ integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
-signal-exit@^3.0.0, signal-exit@^3.0.2:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
- integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
+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"
simple-concat@^1.0.0:
version "1.0.1"
@@ -6254,32 +7274,46 @@ simple-concat@^1.0.0:
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^2.7.0:
- version "2.8.1"
- resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d"
- integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==
+ version "2.8.2"
+ resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019"
+ integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==
dependencies:
decompress-response "^3.3.0"
once "^1.3.1"
simple-concat "^1.0.0"
-slash@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
- integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
+sinon@19.0.2:
+ version "19.0.2"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-19.0.2.tgz#944cf771d22236aa84fc1ab70ce5bffc3a215dad"
+ integrity sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==
+ dependencies:
+ "@sinonjs/commons" "^3.0.1"
+ "@sinonjs/fake-timers" "^13.0.2"
+ "@sinonjs/samsam" "^8.0.1"
+ diff "^7.0.0"
+ nise "^6.1.1"
+ supports-color "^7.2.0"
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@^2.1.0:
+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"
+
+snake-case@^2.1.0:
version "2.1.0"
- resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
- integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==
+ resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f"
+ integrity sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==
dependencies:
- ansi-styles "^3.2.0"
- astral-regex "^1.0.0"
- is-fullwidth-code-point "^2.0.0"
+ no-case "^2.2.0"
solc@0.6.12:
version "0.6.12"
@@ -6295,80 +7329,90 @@ solc@0.6.12:
semver "^5.5.0"
tmp "0.0.33"
-solhint@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.1.0.tgz#50d58c9af921a01350164350144a9809d5ec2975"
- integrity sha512-Cc0wqKzg0NviDF7H5zsrGJ/hVwwkGqi0Hkc3YtedTev4alkJv4YADdJg4y586MpfEvMX4QPp7LugsmJzoeChkQ==
+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:
- "@solidity-parser/parser" "^0.6.0"
- ajv "^6.6.1"
- antlr4 "4.7.1"
- ast-parents "0.0.1"
- chalk "^2.4.2"
- commander "2.18.0"
- cosmiconfig "^5.0.7"
- eslint "^5.6.0"
- fast-diff "^1.1.2"
- glob "^7.1.3"
- ignore "^4.0.6"
- js-yaml "^3.12.0"
- lodash "^4.17.11"
+ 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"
+
+solc@^0.4.20:
+ version "0.4.26"
+ resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5"
+ integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==
+ dependencies:
+ fs-extra "^0.30.0"
+ memorystream "^0.3.1"
+ require-from-string "^1.1.0"
+ semver "^5.3.0"
+ yargs "^4.7.1"
+
+solhint@3.4.1:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.4.1.tgz#8ea15b21c13d1be0b53fd46d605a24d0b36a0c46"
+ integrity sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==
+ 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 "^6.3.0"
+ strip-ansi "^6.0.1"
+ table "^6.8.1"
+ text-table "^0.2.0"
optionalDependencies:
- prettier "^1.14.3"
+ prettier "^2.8.3"
-solidity-coverage@^0.7.9:
- version "0.7.9"
- resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.7.9.tgz#6d1c40639066b93c67b21da48f4bc27ae01f0e58"
- integrity sha512-UWkl0iNmpjuVanPWvZzF6eCAKwbEmmolmzwbN8nU+MexOKO3eW6kVbxBkfEjVa8TuQcLb0F2wdgXJZBRbjpjnA==
+solidity-coverage@0.8.9:
+ version "0.8.9"
+ resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.9.tgz#d885207df927faf6b4f729904fab8ce0943cfd14"
+ integrity sha512-ZhPsxlsLkYyzgwoVGh8RBN2ju7JVahvMkk+8RBVc0vP/3UNq88GzvL8kvbuY48lVIRL8eQjJ+0X8al2Bu9/2iQ==
dependencies:
- "@solidity-parser/parser" "^0.6.0"
- "@truffle/provider" "^0.1.17"
+ "@ethersproject/abi" "^5.0.9"
+ "@solidity-parser/parser" "^0.18.0"
chalk "^2.4.2"
death "^1.1.0"
- detect-port "^1.3.0"
+ difflib "^0.2.4"
fs-extra "^8.1.0"
- ganache-cli "6.9.0"
ghost-testrpc "^0.0.2"
global-modules "^2.0.0"
globby "^10.0.1"
jsonschema "^1.2.4"
lodash "^4.17.15"
+ mocha "^10.2.0"
node-emoji "^1.10.0"
pify "^4.0.1"
recursive-readdir "^2.2.2"
sc-istanbul "^0.4.5"
+ semver "^7.3.4"
shelljs "^0.8.3"
- web3 "1.2.6"
-
-source-map-support@0.5.12:
- version "0.5.12"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599"
- integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
+ web3-utils "^1.3.6"
-source-map-support@^0.4.15:
- version "0.4.18"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
- integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==
- dependencies:
- source-map "^0.5.6"
-
-source-map-support@^0.5.17, source-map-support@^0.5.19:
- version "0.5.19"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
- integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
+source-map-support@^0.5.13, source-map-support@^0.5.19:
+ version "0.5.21"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
+ integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
-source-map@^0.5.6, source-map@^0.5.7:
- version "0.5.7"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
- integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-
source-map@^0.6.0, source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
@@ -6377,14 +7421,19 @@ source-map@^0.6.0, source-map@^0.6.1:
source-map@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
- integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50=
+ integrity sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==
dependencies:
amdefine ">=0.0.4"
+sparse-array@^1.3.1:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/sparse-array/-/sparse-array-1.3.2.tgz#0e1a8b71706d356bc916fe754ff496d450ec20b0"
+ integrity sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg==
+
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"
@@ -6403,19 +7452,19 @@ spdx-expression-parse@^3.0.0:
spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0:
- version "3.0.5"
- resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654"
- integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==
+ version "3.0.13"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5"
+ integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
- integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
+ integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
sshpk@^1.7.0:
- version "1.16.1"
- resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
- integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
+ integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
@@ -6427,17 +7476,48 @@ sshpk@^1.7.0:
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
-"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
- integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
+stable@^0.1.8:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
+ integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
+
+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==
+
+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==
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
- integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
+ integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==
+
+string-format@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b"
+ integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==
+
+string-width@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+ integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ strip-ansi "^3.0.0"
-"string-width@^1.0.2 || 2", string-width@^2.1.0:
+"string-width@^1.0.2 || 2", 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==
@@ -6454,39 +7534,41 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
-string-width@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
- integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
+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.0"
+ strip-ansi "^6.0.1"
-string.prototype.trim@~1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782"
- integrity sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==
+string.prototype.trim@^1.2.7:
+ 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:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- function-bind "^1.1.1"
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
-string.prototype.trimend@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
- integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==
+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:
- define-properties "^1.1.3"
- es-abstract "^1.17.5"
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
-string.prototype.trimstart@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54"
- integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==
+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:
- define-properties "^1.1.3"
- es-abstract "^1.17.5"
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
string_decoder@^1.1.1:
version "1.3.0"
@@ -6495,11 +7577,6 @@ string_decoder@^1.1.1:
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 sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
-
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
@@ -6507,17 +7584,17 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-strip-ansi@^3.0.0:
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
- integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
+ integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
dependencies:
ansi-regex "^2.0.0"
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
- integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
+ integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==
dependencies:
ansi-regex "^3.0.0"
@@ -6528,68 +7605,72 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
-strip-ansi@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
- integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
+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@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
+ integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==
dependencies:
- ansi-regex "^5.0.0"
+ is-utf8 "^0.2.0"
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
- integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
-
-strip-dirs@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5"
- integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==
- dependencies:
- is-natural-number "^4.0.1"
-
-strip-eof@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
- integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
+ integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
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 sha1-DF8VX+8RUTczd96du1iNoFUA428=
+ integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==
dependencies:
is-hex-prefixed "1.0.0"
-strip-json-comments@3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
- integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==
+strip-indent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
+ integrity sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==
+
+strip-indent@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
+ integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
+ dependencies:
+ min-indent "^1.0.0"
-strip-json-comments@^2.0.1:
+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 sha1-PFMZQukIwml8DsNEhYwobHygpgo=
+ integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
-strip-json-comments@^3.1.0:
+strip-json-comments@3.1.1, strip-json-comments@^3.1.0, 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@7.1.0, supports-color@^7.1.0:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
- integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
+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 "^4.0.0"
+ has-flag "^3.0.0"
-supports-color@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
- integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
+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@^3.1.0:
version "3.2.3"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
- integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=
+ integrity sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==
dependencies:
has-flag "^1.0.0"
@@ -6600,34 +7681,36 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.0.0"
-swarm-js@0.1.39:
- version "0.1.39"
- resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.39.tgz#79becb07f291d4b2a178c50fee7aa6e10342c0e8"
- integrity sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg==
+supports-color@^7.1.0, supports-color@^7.2.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:
- bluebird "^3.5.0"
- buffer "^5.0.5"
- decompress "^4.0.0"
- eth-lib "^0.1.26"
- fs-extra "^4.0.2"
- got "^7.1.0"
- mime-types "^2.1.16"
- mkdirp-promise "^5.0.1"
- mock-fs "^4.1.0"
- setimmediate "^1.0.5"
- tar "^4.0.2"
- xhr-request-promise "^0.1.2"
+ 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==
+
+swap-case@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3"
+ integrity sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==
+ dependencies:
+ lower-case "^1.1.1"
+ upper-case "^1.1.1"
swarm-js@^0.1.40:
- version "0.1.40"
- resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99"
- integrity sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==
+ version "0.1.42"
+ resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979"
+ integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==
dependencies:
bluebird "^3.5.0"
buffer "^5.0.5"
eth-lib "^0.1.26"
fs-extra "^4.0.2"
- got "^7.1.0"
+ got "^11.8.5"
mime-types "^2.1.16"
mkdirp-promise "^5.0.1"
mock-fs "^4.1.0"
@@ -6635,121 +7718,103 @@ swarm-js@^0.1.40:
tar "^4.0.2"
xhr-request "^1.0.1"
-table@^5.2.3:
- version "5.4.6"
- resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
- integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
+sync-request@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68"
+ integrity sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==
dependencies:
- ajv "^6.10.2"
- lodash "^4.17.14"
- slice-ansi "^2.1.0"
- string-width "^3.0.0"
+ http-response-object "^3.0.1"
+ sync-rpc "^1.2.1"
+ then-request "^6.0.0"
-tape@^4.6.3:
- version "4.13.3"
- resolved "https://registry.yarnpkg.com/tape/-/tape-4.13.3.tgz#51b3d91c83668c7a45b1a594b607dee0a0b46278"
- integrity sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw==
- dependencies:
- deep-equal "~1.1.1"
- defined "~1.0.0"
- dotignore "~0.1.2"
- for-each "~0.3.3"
- function-bind "~1.1.1"
- glob "~7.1.6"
- has "~1.0.3"
- inherits "~2.0.4"
- is-regex "~1.0.5"
- minimist "~1.2.5"
- object-inspect "~1.7.0"
- resolve "~1.17.0"
- resumer "~0.0.0"
- string.prototype.trim "~1.2.1"
- through "~2.3.8"
-
-tar-stream@^1.5.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"
+sync-rpc@^1.2.1:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7"
+ integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==
+ dependencies:
+ get-port "^3.1.0"
-tar@^4.0.2:
- version "4.4.13"
- resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
- integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
- dependencies:
- chownr "^1.1.1"
- fs-minipass "^1.2.5"
- minipass "^2.8.6"
- minizlib "^1.2.1"
- mkdirp "^0.5.0"
- safe-buffer "^5.1.2"
- yallist "^3.0.3"
+table-layout@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04"
+ integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==
+ dependencies:
+ array-back "^4.0.1"
+ deep-extend "~0.6.0"
+ typical "^5.2.0"
+ wordwrapjs "^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"
- integrity sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=
+table@^6.0.9, 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"
+
+tar@^4.0.2:
+ version "4.4.19"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
+ integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==
dependencies:
- array-back "^1.0.3"
- typical "^2.6.0"
+ chownr "^1.1.4"
+ fs-minipass "^1.2.7"
+ minipass "^2.9.0"
+ minizlib "^1.3.3"
+ mkdirp "^0.5.5"
+ safe-buffer "^5.2.1"
+ yallist "^3.1.1"
+
+testrpc@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed"
+ integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
- integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
+ integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
-through2@^2.0.3:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
- integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
+then-request@^6.0.0:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c"
+ integrity sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==
dependencies:
- readable-stream "~2.3.6"
- xtend "~4.0.1"
-
-through@^2.3.6, through@^2.3.8, through@~2.3.4, through@~2.3.8:
- version "2.3.8"
- resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
- integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
-
-timed-out@^4.0.0, timed-out@^4.0.1:
+ "@types/concat-stream" "^1.6.0"
+ "@types/form-data" "0.0.33"
+ "@types/node" "^8.0.0"
+ "@types/qs" "^6.2.31"
+ caseless "~0.12.0"
+ concat-stream "^1.6.0"
+ form-data "^2.2.0"
+ http-basic "^8.1.1"
+ http-response-object "^3.0.1"
+ promise "^8.0.0"
+ qs "^6.4.0"
+
+timed-out@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
- integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
+ integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==
+
+title-case@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa"
+ integrity sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==
+ dependencies:
+ no-case "^2.2.0"
+ upper-case "^1.0.3"
-tmp@0.0.33, tmp@^0.0.33:
+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-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"
- integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=
-
-to-fast-properties@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
- integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
-
-to-readable-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
- integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
-
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"
@@ -6757,12 +7822,12 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
-toidentifier@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
- integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
+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==
-tough-cookie@~2.5.0:
+tough-cookie@^2.3.3, 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==
@@ -6770,89 +7835,103 @@ tough-cookie@~2.5.0:
psl "^1.1.28"
punycode "^2.1.1"
-trim-right@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
- integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
+tr46@~0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
+ integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
-truffle@^5.1.35:
- version "5.1.35"
- resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.1.35.tgz#9b3adfd3aca1a3b6dd00874bc57d7569a3e3b89c"
- integrity sha512-N2b/3OF84c/4jqmPJ4JgQU1g91Cai4JMKdJ3HLUsmEKmo1LZ84+Y0UIeVBFjWHtTX6H7/oXlvZ59xUVzxXyAsg==
- dependencies:
- app-module-path "^2.2.0"
- mocha "8.0.1"
- original-require "1.0.1"
+trim-newlines@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144"
+ integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
-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@^6.0.3:
- version "6.0.7"
- resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-6.0.7.tgz#5f4880911b7581a873783740ce8b94da163d18a6"
- integrity sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==
-
-ts-generator@^0.0.8:
- version "0.0.8"
- resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.0.8.tgz#7bd48ca064db026d9520bcb682b69efc20971d6a"
- integrity sha512-Gi+aZCELpVL7Mqb+GuMgM+n8JZ/arZZib1iD/R9Ok8JDjOCOCrqS9b1lr72ku7J45WeDCFZxyJoRsiQvhokCnw==
- dependencies:
- "@types/mkdirp" "^0.5.2"
- "@types/prettier" "^1.13.2"
- "@types/resolve" "^0.0.8"
- chalk "^2.4.1"
- glob "^7.1.2"
- mkdirp "^0.5.1"
- prettier "^1.14.2"
- resolve "^1.8.1"
- ts-essentials "^1.0.0"
-
-ts-node@^8.10.2:
- version "8.10.2"
- resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d"
- integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==
+ts-command-line-args@^2.2.0:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0"
+ integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==
dependencies:
+ chalk "^4.1.0"
+ command-line-args "^5.1.1"
+ command-line-usage "^6.1.0"
+ string-format "^2.0.0"
+
+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-node@10.9.1:
+ 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"
- source-map-support "^0.5.17"
+ v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
-tsconfig-paths@^3.9.0:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
- integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==
+tsconfig-paths@^3.14.1:
+ 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.1"
- minimist "^1.2.0"
+ json5 "^1.0.2"
+ minimist "^1.2.6"
strip-bom "^3.0.0"
-tslib@^1.8.1, tslib@^1.9.0:
- version "1.13.0"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
- integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
+tslib@2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+
+tslib@^1.8.1, 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==
+
+tsort@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786"
+ integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==
tsutils@^3.17.1:
- version "3.17.1"
- resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
- integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
+ integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
dependencies:
tslib "^1.8.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
- integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
+ integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
dependencies:
safe-buffer "^5.0.1"
+tweetnacl-util@^0.15.1:
+ version "0.15.1"
+ resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b"
+ integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==
+
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
- integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
+ 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"
@@ -6864,21 +7943,51 @@ type-check@^0.4.0, type-check@~0.4.0:
type-check@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
- integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
+ integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==
dependencies:
prelude-ls "~1.1.2"
-type-detect@^4.0.0, type-detect@^4.0.5:
+type-detect@4.0.8, 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-detect@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c"
+ integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==
+
+type-fest@^0.18.0:
+ version "0.18.1"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f"
+ integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==
+
+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.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
+ integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
+
+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==
+
type-fest@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
-type-is@~1.6.17, type-is@~1.6.18:
+type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
@@ -6891,23 +8000,65 @@ type@^1.0.1:
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
-type@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3"
- integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==
+type@^2.7.2:
+ version "2.7.2"
+ resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
+ integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
-typechain@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/typechain/-/typechain-2.0.0.tgz#62143b48cdf8f95a777f1b76617af077b2d44eee"
- integrity sha512-O+hsAUwtBpqCfoq46Grm52OEdm0GBEu78LxrEzkkGdwUdCoCZpNb2HPzPoNB1MXiRnNhEOGMFyf05UbT2/bUEw==
+typechain@8.3.1:
+ version "8.3.1"
+ resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.1.tgz#dccbc839b94877997536c356380eff7325395cfb"
+ integrity sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ==
dependencies:
- command-line-args "^4.0.7"
- debug "^4.1.1"
+ "@types/prettier" "^2.1.1"
+ debug "^4.3.1"
fs-extra "^7.0.0"
+ glob "7.1.7"
js-sha3 "^0.8.0"
lodash "^4.17.15"
- ts-essentials "^6.0.3"
- ts-generator "^0.0.8"
+ mkdirp "^1.0.4"
+ prettier "^2.3.1"
+ ts-command-line-args "^2.2.0"
+ ts-essentials "^7.0.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-to-buffer@^3.1.5:
version "3.1.5"
@@ -6919,86 +8070,119 @@ typedarray-to-buffer@^3.1.5:
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
- integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
+ integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
-typescript@^3.9.7:
- version "3.9.7"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
- integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==
+typescript@5.1.6:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274"
+ integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
+
+typical@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4"
+ integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==
-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 sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=
+typical@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066"
+ integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==
uglify-js@^3.1.4:
- version "3.10.0"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.10.0.tgz#397a7e6e31ce820bfd1cb55b804ee140c587a9e7"
- integrity sha512-Esj5HG5WAyrLIdYU74Z3JdG2PxdIusvj6IWHMtlyESxc7kcDz7zYlYjpnSokn1UbpV0d/QX9fan7gkCNd/9BQA==
+ version "3.17.4"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c"
+ integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==
+
+uint8arrays@^2.0.5, uint8arrays@^2.1.2:
+ version "2.1.10"
+ resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-2.1.10.tgz#34d023c843a327c676e48576295ca373c56e286a"
+ integrity sha512-Q9/hhJa2836nQfEJSZTmr+pg9+cDJS9XEAp7N2Vg5MzL3bK/mkMVfjscRGYruP9jNda6MAdf4QD/y78gSzkp6A==
+ dependencies:
+ multiformats "^9.4.2"
+
+uint8arrays@^3.0.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0"
+ integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==
+ dependencies:
+ multiformats "^9.4.2"
ultron@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==
-unbzip2-stream@^1.0.9:
- version "1.4.3"
- resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7"
- integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==
+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:
- buffer "^5.2.1"
- through "^2.3.8"
+ call-bind "^1.0.2"
+ has-bigints "^1.0.2"
+ has-symbols "^1.0.3"
+ which-boxed-primitive "^1.0.2"
-underscore@1.9.1:
- version "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==
+underscore@^1.8.3:
+ version "1.13.6"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441"
+ integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==
+
+undici-types@~6.13.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5"
+ integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==
+
+undici@^5.14.0:
+ version "5.28.3"
+ resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.3.tgz#a731e0eff2c3fcfd41c1169a869062be222d1e5b"
+ integrity sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==
+ dependencies:
+ "@fastify/busboy" "^2.0.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, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
- integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
+ integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
-uri-js@^4.2.2:
- version "4.2.2"
- resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
- integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
+upper-case-first@^1.1.0, upper-case-first@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115"
+ integrity sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==
dependencies:
- punycode "^2.1.0"
+ upper-case "^1.1.1"
-url-parse-lax@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
- integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=
- dependencies:
- prepend-http "^1.0.1"
+upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
+ integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==
-url-parse-lax@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
- integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
+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:
- prepend-http "^2.0.0"
+ punycode "^2.1.0"
url-set-query@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339"
- integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=
-
-url-template@^2.0.8:
- version "2.0.8"
- resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21"
- integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE=
+ integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==
-url-to-options@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
- integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
+utf-8-validate@^5.0.2:
+ version "5.0.10"
+ resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2"
+ integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==
+ dependencies:
+ node-gyp-build "^4.3.0"
utf8@3.0.0, utf8@^3.0.0:
version "3.0.0"
@@ -7008,37 +8192,53 @@ utf8@3.0.0, utf8@^3.0.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 sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+ integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+
+util@^0.12.5:
+ version "0.12.5"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc"
+ integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==
+ dependencies:
+ inherits "^2.0.3"
+ is-arguments "^1.0.4"
+ is-generator-function "^1.0.7"
+ is-typed-array "^1.1.3"
+ which-typed-array "^1.1.2"
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
- integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
+ 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 sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=
-
-uuid@3.3.2:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
- integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
+ integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-uuid@^8.0.0:
- version "8.2.0"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.2.0.tgz#cb10dd6b118e2dada7d0cd9730ba7417c93d920e"
- integrity sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==
+uuid@^8.3.2:
+ version "8.3.2"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
+uuid@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
+ integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
+
+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==
v8-compile-cache@^2.0.3:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
- integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
+ integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
validate-npm-package-license@^3.0.1:
version "3.0.4"
@@ -7048,1015 +8248,561 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
-varint@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.0.tgz#d826b89f7490732fabc0c0ed693ed475dcb29ebf"
- integrity sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8=
+varint@^5.0.0, varint@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4"
+ integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==
+
+varint@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0"
+ integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
- integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
+ integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
- integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
+ integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
-web3-bzz@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.1.tgz#c3bd1e8f0c02a13cd6d4e3c3e9e1713f144f6f0d"
- integrity sha512-LdOO44TuYbGIPfL4ilkuS89GQovxUpmLz6C1UC7VYVVRILeZS740FVB3j9V4P4FHUk1RenaDfKhcntqgVCHtjw==
- dependencies:
- got "9.6.0"
- swarm-js "0.1.39"
- underscore "1.9.1"
-
-web3-bzz@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f"
- integrity sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==
+web3-bzz@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.10.0.tgz#ac74bc71cdf294c7080a79091079192f05c5baed"
+ integrity sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA==
dependencies:
"@types/node" "^12.12.6"
- got "9.6.0"
+ got "12.1.0"
swarm-js "^0.1.40"
- underscore "1.9.1"
-
-web3-bzz@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.2.tgz#a3b9f613c49fd3e120e0997088a73557d5adb724"
- integrity sha512-b1O2ObsqUN1lJxmFSjvnEC4TsaCbmh7Owj3IAIWTKqL9qhVgx7Qsu5O9cD13pBiSPNZJ68uJPaKq380QB4NWeA==
- dependencies:
- "@types/node" "^10.12.18"
- got "9.6.0"
- swarm-js "0.1.39"
- underscore "1.9.1"
-
-web3-bzz@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.6.tgz#0b88c0b96029eaf01b10cb47c4d5f79db4668883"
- integrity sha512-9NiHLlxdI1XeFtbPJAmi2jnnIHVF+GNy517wvOS72P7ZfuJTPwZaSNXfT01vWgPPE9R96/uAHDWHOg+T4WaDQQ==
- dependencies:
- "@types/node" "^10.12.18"
- got "9.6.0"
- swarm-js "0.1.39"
- underscore "1.9.1"
-
-web3-core-helpers@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.1.tgz#f5f32d71c60a4a3bd14786118e633ce7ca6d5d0d"
- integrity sha512-Gx3sTEajD5r96bJgfuW377PZVFmXIH4TdqDhgGwd2lZQCcMi+DA4TgxJNJGxn0R3aUVzyyE76j4LBrh412mXrw==
- dependencies:
- underscore "1.9.1"
- web3-eth-iban "1.2.1"
- web3-utils "1.2.1"
-
-web3-core-helpers@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz#84c681ed0b942c0203f3b324a245a127e8c67a99"
- integrity sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==
- dependencies:
- underscore "1.9.1"
- web3-eth-iban "1.2.11"
- web3-utils "1.2.11"
-
-web3-core-helpers@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.2.tgz#484974f4bd4a487217b85b0d7cfe841af0907619"
- integrity sha512-HJrRsIGgZa1jGUIhvGz4S5Yh6wtOIo/TMIsSLe+Xay+KVnbseJpPprDI5W3s7H2ODhMQTbogmmUFquZweW2ImQ==
- dependencies:
- underscore "1.9.1"
- web3-eth-iban "1.2.2"
- web3-utils "1.2.2"
-
-web3-core-helpers@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.6.tgz#7aacd25bf8015adcdfc0f3243d0dcfdff0373f7d"
- integrity sha512-gYKWmC2HmO7RcDzpo4L1K8EIoy5L8iubNDuTC6q69UxczwqKF/Io0kbK/1Z10Av++NlzOSiuyGp2gc4t4UOsDw==
- dependencies:
- underscore "1.9.1"
- web3-eth-iban "1.2.6"
- web3-utils "1.2.6"
-web3-core-method@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.1.tgz#9df1bafa2cd8be9d9937e01c6a47fc768d15d90a"
- integrity sha512-Ghg2WS23qi6Xj8Od3VCzaImLHseEA7/usvnOItluiIc5cKs00WYWsNy2YRStzU9a2+z8lwQywPYp0nTzR/QXdQ==
- dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.1"
- web3-core-promievent "1.2.1"
- web3-core-subscriptions "1.2.1"
- web3-utils "1.2.1"
-
-web3-core-method@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.11.tgz#f880137d1507a0124912bf052534f168b8d8fbb6"
- integrity sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==
- dependencies:
- "@ethersproject/transactions" "^5.0.0-beta.135"
- underscore "1.9.1"
- web3-core-helpers "1.2.11"
- web3-core-promievent "1.2.11"
- web3-core-subscriptions "1.2.11"
- web3-utils "1.2.11"
-
-web3-core-method@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.2.tgz#d4fe2bb1945b7152e5f08e4ea568b171132a1e56"
- integrity sha512-szR4fDSBxNHaF1DFqE+j6sFR/afv9Aa36OW93saHZnrh+iXSrYeUUDfugeNcRlugEKeUCkd4CZylfgbK2SKYJA==
+web3-bzz@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.10.1.tgz#29edb8e91e806a4cf69de0735b4cdc18b21fb4f0"
+ integrity sha512-0T2BTYm9mLPpnRJuXSS7PA39dTXCPj6a3/Qdee84Plm6WsSIl4aZooJ4YUMnlII8HjyzwiIzjnH7AEZrBcBu9w==
dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.2"
- web3-core-promievent "1.2.2"
- web3-core-subscriptions "1.2.2"
- web3-utils "1.2.2"
+ "@types/node" "^12.12.6"
+ got "12.1.0"
+ swarm-js "^0.1.40"
-web3-core-method@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.6.tgz#f5a3e4d304abaf382923c8ab88ec8eeef45c1b3b"
- integrity sha512-r2dzyPEonqkBg7Mugq5dknhV5PGaZTHBZlS/C+aMxNyQs3T3eaAsCTqlQDitwNUh/sUcYPEGF0Vo7ahYK4k91g==
+web3-core-helpers@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.0.tgz#1016534c51a5df77ed4f94d1fcce31de4af37fad"
+ integrity sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g==
dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.6"
- web3-core-promievent "1.2.6"
- web3-core-subscriptions "1.2.6"
- web3-utils "1.2.6"
+ web3-eth-iban "1.10.0"
+ web3-utils "1.10.0"
-web3-core-promievent@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.1.tgz#003e8a3eb82fb27b6164a6d5b9cad04acf733838"
- integrity sha512-IVUqgpIKoeOYblwpex4Hye6npM0aMR+kU49VP06secPeN0rHMyhGF0ZGveWBrGvf8WDPI7jhqPBFIC6Jf3Q3zw==
+web3-core-helpers@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.1.tgz#dd597adc758efe03b380f1423a4da3de1757530b"
+ integrity sha512-lgOgdiIyIIXxIVjEHjT8PC2CsjFvvBXfVF0Xq5SiRcPKj47B2F7uur0gPoPc6e6+kjo49qEqLlx6eZKOkCAR1A==
dependencies:
- any-promise "1.3.0"
- eventemitter3 "3.1.2"
+ web3-eth-iban "1.10.1"
+ web3-utils "1.10.1"
-web3-core-promievent@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz#51fe97ca0ddec2f99bf8c3306a7a8e4b094ea3cf"
- integrity sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==
+web3-core-method@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.0.tgz#82668197fa086e8cc8066742e35a9d72535e3412"
+ integrity sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA==
+ dependencies:
+ "@ethersproject/transactions" "^5.6.2"
+ web3-core-helpers "1.10.0"
+ web3-core-promievent "1.10.0"
+ web3-core-subscriptions "1.10.0"
+ web3-utils "1.10.0"
+
+web3-core-method@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.1.tgz#decd9a11d95c199960477b297a45b8f135ac7770"
+ integrity sha512-QEqgMsagp6vs0GOlI4QHzZcsvzJs+Zp1Eo8uOZgosYoRfusklzfPmX4OYg4H6XyenCavgvmAkxw0g8y8hlLHiQ==
+ dependencies:
+ "@ethersproject/transactions" "^5.6.2"
+ web3-core-helpers "1.10.1"
+ web3-core-promievent "1.10.1"
+ web3-core-subscriptions "1.10.1"
+ web3-utils "1.10.1"
+
+web3-core-promievent@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.0.tgz#cbb5b3a76b888df45ed3a8d4d8d4f54ccb66a37b"
+ integrity sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg==
dependencies:
eventemitter3 "4.0.4"
-web3-core-promievent@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.2.tgz#3b60e3f2a0c96db8a891c927899d29d39e66ab1c"
- integrity sha512-tKvYeT8bkUfKABcQswK6/X79blKTKYGk949urZKcLvLDEaWrM3uuzDwdQT3BNKzQ3vIvTggFPX9BwYh0F1WwqQ==
- dependencies:
- any-promise "1.3.0"
- eventemitter3 "3.1.2"
-
-web3-core-promievent@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.6.tgz#b1550a3a4163e48b8b704c1fe4b0084fc2dad8f5"
- integrity sha512-km72kJef/qtQNiSjDJJVHIZvoVOm6ytW3FCYnOcCs7RIkviAb5JYlPiye0o4pJOLzCXYID7DK7Q9bhY8qWb1lw==
- dependencies:
- any-promise "1.3.0"
- eventemitter3 "3.1.2"
-
-web3-core-requestmanager@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.1.tgz#fa2e2206c3d738db38db7c8fe9c107006f5c6e3d"
- integrity sha512-xfknTC69RfYmLKC+83Jz73IC3/sS2ZLhGtX33D4Q5nQ8yc39ElyAolxr9sJQS8kihOcM6u4J+8gyGMqsLcpIBg==
- dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.1"
- web3-providers-http "1.2.1"
- web3-providers-ipc "1.2.1"
- web3-providers-ws "1.2.1"
-
-web3-core-requestmanager@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz#fe6eb603fbaee18530293a91f8cf26d8ae28c45a"
- integrity sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==
- dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.11"
- web3-providers-http "1.2.11"
- web3-providers-ipc "1.2.11"
- web3-providers-ws "1.2.11"
-
-web3-core-requestmanager@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.2.tgz#667ba9ac724c9c76fa8965ae8a3c61f66e68d8d6"
- integrity sha512-a+gSbiBRHtHvkp78U2bsntMGYGF2eCb6219aMufuZWeAZGXJ63Wc2321PCbA8hF9cQrZI4EoZ4kVLRI4OF15Hw==
- dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.2"
- web3-providers-http "1.2.2"
- web3-providers-ipc "1.2.2"
- web3-providers-ws "1.2.2"
-
-web3-core-requestmanager@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.6.tgz#5808c0edc0d6e2991a87b65508b3a1ab065b68ec"
- integrity sha512-QU2cbsj9Dm0r6om40oSwk8Oqbp3wTa08tXuMpSmeOTkGZ3EMHJ1/4LiJ8shwg1AvPMrKVU0Nri6+uBNCdReZ+g==
- dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.6"
- web3-providers-http "1.2.6"
- web3-providers-ipc "1.2.6"
- web3-providers-ws "1.2.6"
-
-web3-core-subscriptions@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.1.tgz#8c2368a839d4eec1c01a4b5650bbeb82d0e4a099"
- integrity sha512-nmOwe3NsB8V8UFsY1r+sW6KjdOS68h8nuh7NzlWxBQT/19QSUGiERRTaZXWu5BYvo1EoZRMxCKyCQpSSXLc08g==
- dependencies:
- eventemitter3 "3.1.2"
- underscore "1.9.1"
- web3-core-helpers "1.2.1"
-
-web3-core-subscriptions@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz#beca908fbfcb050c16f45f3f0f4c205e8505accd"
- integrity sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==
+web3-core-promievent@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.1.tgz#d20b1328d1ff8881acb8cf4b5749bb2218798b0e"
+ integrity sha512-ggInbRxkx0n0FVMU5GXx9pbTwq7rfF2DJ6J6AafifOC0P0269TbHfFKMlU7B5K5i6/VQxrsY9fBPf6am9DmQuw==
dependencies:
eventemitter3 "4.0.4"
- underscore "1.9.1"
- web3-core-helpers "1.2.11"
-
-web3-core-subscriptions@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.2.tgz#bf4ba23a653a003bdc3551649958cc0b080b068e"
- integrity sha512-QbTgigNuT4eicAWWr7ahVpJyM8GbICsR1Ys9mJqzBEwpqS+RXTRVSkwZ2IsxO+iqv6liMNwGregbJLq4urMFcQ==
- dependencies:
- eventemitter3 "3.1.2"
- underscore "1.9.1"
- web3-core-helpers "1.2.2"
-web3-core-subscriptions@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.6.tgz#9d44189e2321f8f1abc31f6c09103b5283461b57"
- integrity sha512-M0PzRrP2Ct13x3wPulFtc5kENH4UtnPxO9YxkfQlX2WRKENWjt4Rfq+BCVGYEk3rTutDfWrjfzjmqMRvXqEY5Q==
+web3-core-requestmanager@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.0.tgz#4b34f6e05837e67c70ff6f6993652afc0d54c340"
+ integrity sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ==
+ dependencies:
+ util "^0.12.5"
+ web3-core-helpers "1.10.0"
+ web3-providers-http "1.10.0"
+ web3-providers-ipc "1.10.0"
+ web3-providers-ws "1.10.0"
+
+web3-core-requestmanager@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.1.tgz#f0c765ae811c1c0b24c7c8ede8e9a254bc520fce"
+ integrity sha512-hBHuKbh8PGrSs4vTg2EA7xM+BIDVOrmOZnK4I+KeWw8zZr6bmhhk8xkmtKo2/0fADAkvVqMiJwuZcpRr3DILnw==
+ dependencies:
+ util "^0.12.5"
+ web3-core-helpers "1.10.1"
+ web3-providers-http "1.10.1"
+ web3-providers-ipc "1.10.1"
+ web3-providers-ws "1.10.1"
+
+web3-core-subscriptions@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.0.tgz#b534592ee1611788fc0cb0b95963b9b9b6eacb7c"
+ integrity sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g==
dependencies:
- eventemitter3 "3.1.2"
- underscore "1.9.1"
- web3-core-helpers "1.2.6"
+ eventemitter3 "4.0.4"
+ web3-core-helpers "1.10.0"
-web3-core@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.1.tgz#7278b58fb6495065e73a77efbbce781a7fddf1a9"
- integrity sha512-5ODwIqgl8oIg/0+Ai4jsLxkKFWJYE0uLuE1yUKHNVCL4zL6n3rFjRMpKPokd6id6nJCNgeA64KdWQ4XfpnjdMg==
+web3-core-subscriptions@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.1.tgz#1e19ef59f9844c31a85f1b9c17088a786029c118"
+ integrity sha512-6B7cA7lUwCAh7X55gTMfFkC9L8en3bddqFi+VNO9SO9af62t2L5xTb8pxZEFirIF4s4qKxKekLgZrRhpmlO3eA==
dependencies:
- web3-core-helpers "1.2.1"
- web3-core-method "1.2.1"
- web3-core-requestmanager "1.2.1"
- web3-utils "1.2.1"
+ eventemitter3 "4.0.4"
+ web3-core-helpers "1.10.1"
-web3-core@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.11.tgz#1043cacc1becb80638453cc5b2a14be9050288a7"
- integrity sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==
+web3-core@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.0.tgz#9aa07c5deb478cf356c5d3b5b35afafa5fa8e633"
+ integrity sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ==
dependencies:
- "@types/bn.js" "^4.11.5"
+ "@types/bn.js" "^5.1.1"
"@types/node" "^12.12.6"
bignumber.js "^9.0.0"
- web3-core-helpers "1.2.11"
- web3-core-method "1.2.11"
- web3-core-requestmanager "1.2.11"
- web3-utils "1.2.11"
-
-web3-core@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.2.tgz#334b99c8222ef9cfd0339e27352f0b58ea789a2f"
- integrity sha512-miHAX3qUgxV+KYfaOY93Hlc3kLW2j5fH8FJy6kSxAv+d4d5aH0wwrU2IIoJylQdT+FeenQ38sgsCnFu9iZ1hCQ==
- dependencies:
- "@types/bn.js" "^4.11.4"
- "@types/node" "^12.6.1"
- web3-core-helpers "1.2.2"
- web3-core-method "1.2.2"
- web3-core-requestmanager "1.2.2"
- web3-utils "1.2.2"
-
-web3-core@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.6.tgz#bb42a1d7ae49a7258460f0d95ddb00906f59ef92"
- integrity sha512-y/QNBFtr5cIR8vxebnotbjWJpOnO8LDYEAzZjeRRUJh2ijmhjoYk7dSNx9ExgC0UCfNFRoNCa9dGRu/GAxwRlw==
- dependencies:
- "@types/bn.js" "^4.11.4"
- "@types/node" "^12.6.1"
- web3-core-helpers "1.2.6"
- web3-core-method "1.2.6"
- web3-core-requestmanager "1.2.6"
- web3-utils "1.2.6"
+ web3-core-helpers "1.10.0"
+ web3-core-method "1.10.0"
+ web3-core-requestmanager "1.10.0"
+ web3-utils "1.10.0"
-web3-eth-abi@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.1.tgz#9b915b1c9ebf82f70cca631147035d5419064689"
- integrity sha512-jI/KhU2a/DQPZXHjo2GW0myEljzfiKOn+h1qxK1+Y9OQfTcBMxrQJyH5AP89O6l6NZ1QvNdq99ThAxBFoy5L+g==
+web3-core@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.1.tgz#a4cb471356c4a197654b61adc9d0b03357da4258"
+ integrity sha512-a45WF/e2VeSs17UTmmWhEaMDv/A+N6qchA7zepvdvwUGCZME39YWCmbsjAYjkq0btsXueOIBpS6fLuq5VoLkFg==
dependencies:
- ethers "4.0.0-beta.3"
- underscore "1.9.1"
- web3-utils "1.2.1"
+ "@types/bn.js" "^5.1.1"
+ "@types/node" "^12.12.6"
+ bignumber.js "^9.0.0"
+ web3-core-helpers "1.10.1"
+ web3-core-method "1.10.1"
+ web3-core-requestmanager "1.10.1"
+ web3-utils "1.10.1"
-web3-eth-abi@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz#a887494e5d447c2926d557a3834edd66e17af9b0"
- integrity sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==
+web3-eth-abi@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.0.tgz#53a7a2c95a571e205e27fd9e664df4919483cce1"
+ integrity sha512-cwS+qRBWpJ43aI9L3JS88QYPfFcSJJ3XapxOQ4j40v6mk7ATpA8CVK1vGTzpihNlOfMVRBkR95oAj7oL6aiDOg==
dependencies:
- "@ethersproject/abi" "5.0.0-beta.153"
- underscore "1.9.1"
- web3-utils "1.2.11"
+ "@ethersproject/abi" "^5.6.3"
+ web3-utils "1.10.0"
-web3-eth-abi@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.2.tgz#d5616d88a90020f894763423a9769f2da11fe37a"
- integrity sha512-Yn/ZMgoOLxhTVxIYtPJ0eS6pnAnkTAaJgUJh1JhZS4ekzgswMfEYXOwpMaD5eiqPJLpuxmZFnXnBZlnQ1JMXsw==
+web3-eth-abi@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.1.tgz#4d64d1d272f35f7aaae7be9679493474e0af86c7"
+ integrity sha512-hk5NyeGweJYTjes7lBW7gtG7iYoN6HLt6E4FQDrHPdwZjwNmvzaOH9N8zMTCxNFXUlg0bzeTOzWwMA717a+4eg==
dependencies:
- ethers "4.0.0-beta.3"
- underscore "1.9.1"
- web3-utils "1.2.2"
+ "@ethersproject/abi" "^5.6.3"
+ web3-utils "1.10.1"
-web3-eth-abi@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.6.tgz#b495383cc5c0d8e2857b26e7fe25606685983b25"
- integrity sha512-w9GAyyikn8nSifSDZxAvU9fxtQSX+W2xQWMmrtTXmBGCaE4/ywKOSPAO78gq8AoU4Wq5yqVGKZLLbfpt7/sHlA==
+web3-eth-accounts@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.0.tgz#2942beca0a4291455f32cf09de10457a19a48117"
+ integrity sha512-wiq39Uc3mOI8rw24wE2n15hboLE0E9BsQLdlmsL4Zua9diDS6B5abXG0XhFcoNsXIGMWXVZz4TOq3u4EdpXF/Q==
dependencies:
- ethers "4.0.0-beta.3"
- underscore "1.9.1"
- web3-utils "1.2.6"
-
-web3-eth-accounts@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.1.tgz#2741a8ef337a7219d57959ac8bd118b9d68d63cf"
- integrity sha512-26I4qq42STQ8IeKUyur3MdQ1NzrzCqPsmzqpux0j6X/XBD7EjZ+Cs0lhGNkSKH5dI3V8CJasnQ5T1mNKeWB7nQ==
- dependencies:
- any-promise "1.3.0"
- crypto-browserify "3.12.0"
- eth-lib "0.2.7"
- scryptsy "2.1.0"
- semver "6.2.0"
- underscore "1.9.1"
- uuid "3.3.2"
- web3-core "1.2.1"
- web3-core-helpers "1.2.1"
- web3-core-method "1.2.1"
- web3-utils "1.2.1"
-
-web3-eth-accounts@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz#a9e3044da442d31903a7ce035a86d8fa33f90520"
- integrity sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==
- dependencies:
- crypto-browserify "3.12.0"
+ "@ethereumjs/common" "2.5.0"
+ "@ethereumjs/tx" "3.3.2"
eth-lib "0.2.8"
- ethereumjs-common "^1.3.2"
- ethereumjs-tx "^2.1.1"
+ ethereumjs-util "^7.1.5"
scrypt-js "^3.0.1"
- underscore "1.9.1"
- uuid "3.3.2"
- web3-core "1.2.11"
- web3-core-helpers "1.2.11"
- web3-core-method "1.2.11"
- web3-utils "1.2.11"
-
-web3-eth-accounts@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.2.tgz#c187e14bff6baa698ac352220290222dbfd332e5"
- integrity sha512-KzHOEyXOEZ13ZOkWN3skZKqSo5f4Z1ogPFNn9uZbKCz+kSp+gCAEKxyfbOsB/JMAp5h7o7pb6eYsPCUBJmFFiA==
- dependencies:
- any-promise "1.3.0"
- crypto-browserify "3.12.0"
- eth-lib "0.2.7"
- ethereumjs-common "^1.3.2"
- ethereumjs-tx "^2.1.1"
- scrypt-shim "github:web3-js/scrypt-shim"
- underscore "1.9.1"
- uuid "3.3.2"
- web3-core "1.2.2"
- web3-core-helpers "1.2.2"
- web3-core-method "1.2.2"
- web3-utils "1.2.2"
-
-web3-eth-accounts@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.6.tgz#a1ba4bf75fa8102a3ec6cddd0eccd72462262720"
- integrity sha512-cDVtonHRgzqi/ZHOOf8kfCQWFEipcfQNAMzXIaKZwc0UUD9mgSI5oJrN45a89Ze+E6Lz9m77cDG5Ax9zscSkcw==
- dependencies:
- "@web3-js/scrypt-shim" "^0.1.0"
- any-promise "1.3.0"
- crypto-browserify "3.12.0"
- eth-lib "^0.2.8"
- ethereumjs-common "^1.3.2"
- ethereumjs-tx "^2.1.1"
- underscore "1.9.1"
- uuid "3.3.2"
- web3-core "1.2.6"
- web3-core-helpers "1.2.6"
- web3-core-method "1.2.6"
- web3-utils "1.2.6"
-
-web3-eth-contract@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.1.tgz#3542424f3d341386fd9ff65e78060b85ac0ea8c4"
- integrity sha512-kYFESbQ3boC9bl2rYVghj7O8UKMiuKaiMkxvRH5cEDHil8V7MGEGZNH0slSdoyeftZVlaWSMqkRP/chfnKND0g==
- dependencies:
- underscore "1.9.1"
- web3-core "1.2.1"
- web3-core-helpers "1.2.1"
- web3-core-method "1.2.1"
- web3-core-promievent "1.2.1"
- web3-core-subscriptions "1.2.1"
- web3-eth-abi "1.2.1"
- web3-utils "1.2.1"
-
-web3-eth-contract@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz#917065902bc27ce89da9a1da26e62ef663663b90"
- integrity sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==
- dependencies:
- "@types/bn.js" "^4.11.5"
- underscore "1.9.1"
- web3-core "1.2.11"
- web3-core-helpers "1.2.11"
- web3-core-method "1.2.11"
- web3-core-promievent "1.2.11"
- web3-core-subscriptions "1.2.11"
- web3-eth-abi "1.2.11"
- web3-utils "1.2.11"
-
-web3-eth-contract@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.2.tgz#84e92714918a29e1028ee7718f0712536e14e9a1"
- integrity sha512-EKT2yVFws3FEdotDQoNsXTYL798+ogJqR2//CaGwx3p0/RvQIgfzEwp8nbgA6dMxCsn9KOQi7OtklzpnJMkjtA==
- dependencies:
- "@types/bn.js" "^4.11.4"
- underscore "1.9.1"
- web3-core "1.2.2"
- web3-core-helpers "1.2.2"
- web3-core-method "1.2.2"
- web3-core-promievent "1.2.2"
- web3-core-subscriptions "1.2.2"
- web3-eth-abi "1.2.2"
- web3-utils "1.2.2"
-
-web3-eth-contract@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.6.tgz#39111543960035ed94c597a239cf5aa1da796741"
- integrity sha512-ak4xbHIhWgsbdPCkSN+HnQc1SH4c856y7Ly+S57J/DQVzhFZemK5HvWdpwadJrQTcHET3ZeId1vq3kmW7UYodw==
- dependencies:
- "@types/bn.js" "^4.11.4"
- underscore "1.9.1"
- web3-core "1.2.6"
- web3-core-helpers "1.2.6"
- web3-core-method "1.2.6"
- web3-core-promievent "1.2.6"
- web3-core-subscriptions "1.2.6"
- web3-eth-abi "1.2.6"
- web3-utils "1.2.6"
-
-web3-eth-ens@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.1.tgz#a0e52eee68c42a8b9865ceb04e5fb022c2d971d5"
- integrity sha512-lhP1kFhqZr2nnbu3CGIFFrAnNxk2veXpOXBY48Tub37RtobDyHijHgrj+xTh+mFiPokyrapVjpFsbGa+Xzye4Q==
- dependencies:
- eth-ens-namehash "2.0.8"
- underscore "1.9.1"
- web3-core "1.2.1"
- web3-core-helpers "1.2.1"
- web3-core-promievent "1.2.1"
- web3-eth-abi "1.2.1"
- web3-eth-contract "1.2.1"
- web3-utils "1.2.1"
-
-web3-eth-ens@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz#26d4d7f16d6cbcfff918e39832b939edc3162532"
- integrity sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==
+ uuid "^9.0.0"
+ web3-core "1.10.0"
+ web3-core-helpers "1.10.0"
+ web3-core-method "1.10.0"
+ web3-utils "1.10.0"
+
+web3-eth-accounts@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.1.tgz#24960e68c1ff3aaa57b96195c151f21bf9b9a0c0"
+ integrity sha512-x8zevaF4FYOIZqR3fdzdeKPf1Ek/O3HFptYH42IucYI5bK+o6ORebDuOOaIZqrF/c8ijcjGoo+cUDN9/5jU6Cw==
+ dependencies:
+ "@ethereumjs/common" "2.5.0"
+ "@ethereumjs/tx" "3.3.2"
+ "@ethereumjs/util" "^8.1.0"
+ eth-lib "0.2.8"
+ scrypt-js "^3.0.1"
+ uuid "^9.0.0"
+ web3-core "1.10.1"
+ web3-core-helpers "1.10.1"
+ web3-core-method "1.10.1"
+ web3-utils "1.10.1"
+
+web3-eth-contract@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.0.tgz#8e68c7654576773ec3c91903f08e49d0242c503a"
+ integrity sha512-MIC5FOzP/+2evDksQQ/dpcXhSqa/2hFNytdl/x61IeWxhh6vlFeSjq0YVTAyIzdjwnL7nEmZpjfI6y6/Ufhy7w==
+ dependencies:
+ "@types/bn.js" "^5.1.1"
+ web3-core "1.10.0"
+ web3-core-helpers "1.10.0"
+ web3-core-method "1.10.0"
+ web3-core-promievent "1.10.0"
+ web3-core-subscriptions "1.10.0"
+ web3-eth-abi "1.10.0"
+ web3-utils "1.10.0"
+
+web3-eth-contract@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.1.tgz#8f8a514db8a1c81337e67a60054840edfc8c26bb"
+ integrity sha512-eRZItYq8LzSPOKqgkTaT1rRruXTNkjbeIe9Cs+VFx3+p/GHyUI1Rj4rfBXp1MBR6p4WK+oy05sB+FNugOYxe8Q==
+ dependencies:
+ "@types/bn.js" "^5.1.1"
+ web3-core "1.10.1"
+ web3-core-helpers "1.10.1"
+ web3-core-method "1.10.1"
+ web3-core-promievent "1.10.1"
+ web3-core-subscriptions "1.10.1"
+ web3-eth-abi "1.10.1"
+ web3-utils "1.10.1"
+
+web3-eth-ens@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.0.tgz#96a676524e0b580c87913f557a13ed810cf91cd9"
+ integrity sha512-3hpGgzX3qjgxNAmqdrC2YUQMTfnZbs4GeLEmy8aCWziVwogbuqQZ+Gzdfrym45eOZodk+lmXyLuAdqkNlvkc1g==
dependencies:
content-hash "^2.5.2"
eth-ens-namehash "2.0.8"
- underscore "1.9.1"
- web3-core "1.2.11"
- web3-core-helpers "1.2.11"
- web3-core-promievent "1.2.11"
- web3-eth-abi "1.2.11"
- web3-eth-contract "1.2.11"
- web3-utils "1.2.11"
-
-web3-eth-ens@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.2.tgz#0a4abed1d4cbdacbf5e1ab06e502d806d1192bc6"
- integrity sha512-CFjkr2HnuyMoMFBoNUWojyguD4Ef+NkyovcnUc/iAb9GP4LHohKrODG4pl76R5u61TkJGobC2ij6TyibtsyVYg==
- dependencies:
- eth-ens-namehash "2.0.8"
- underscore "1.9.1"
- web3-core "1.2.2"
- web3-core-helpers "1.2.2"
- web3-core-promievent "1.2.2"
- web3-eth-abi "1.2.2"
- web3-eth-contract "1.2.2"
- web3-utils "1.2.2"
-
-web3-eth-ens@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.6.tgz#bf86a624c4c72bc59913c2345180d3ea947e110d"
- integrity sha512-8UEqt6fqR/dji/jBGPFAyBs16OJjwi0t2dPWXPyGXmty/fH+osnXwWXE4HRUyj4xuafiM5P1YkXMsPhKEadjiw==
+ web3-core "1.10.0"
+ web3-core-helpers "1.10.0"
+ web3-core-promievent "1.10.0"
+ web3-eth-abi "1.10.0"
+ web3-eth-contract "1.10.0"
+ web3-utils "1.10.0"
+
+web3-eth-ens@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.1.tgz#3064b77f2de2c0f77136479f8b388a48e3fb1a85"
+ integrity sha512-WtcLhYTBeoKj+CbuyG3JQWcQynOXmv/l5CB27C3hJ42WWPa/XfUAsDmPbJp3YkqUbK3lE6iLT2yzwQIHfqmd0g==
dependencies:
+ content-hash "^2.5.2"
eth-ens-namehash "2.0.8"
- underscore "1.9.1"
- web3-core "1.2.6"
- web3-core-helpers "1.2.6"
- web3-core-promievent "1.2.6"
- web3-eth-abi "1.2.6"
- web3-eth-contract "1.2.6"
- web3-utils "1.2.6"
-
-web3-eth-iban@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.1.tgz#2c3801718946bea24e9296993a975c80b5acf880"
- integrity sha512-9gkr4QPl1jCU+wkgmZ8EwODVO3ovVj6d6JKMos52ggdT2YCmlfvFVF6wlGLwi0VvNa/p+0BjJzaqxnnG/JewjQ==
- dependencies:
- bn.js "4.11.8"
- web3-utils "1.2.1"
-
-web3-eth-iban@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz#f5f73298305bc7392e2f188bf38a7362b42144ef"
- integrity sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==
- dependencies:
- bn.js "^4.11.9"
- web3-utils "1.2.11"
-
-web3-eth-iban@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.2.tgz#76bec73bad214df7c4192388979a59fc98b96c5a"
- integrity sha512-gxKXBoUhaTFHr0vJB/5sd4i8ejF/7gIsbM/VvemHT3tF5smnmY6hcwSMmn7sl5Gs+83XVb/BngnnGkf+I/rsrQ==
- dependencies:
- bn.js "4.11.8"
- web3-utils "1.2.2"
-
-web3-eth-iban@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.6.tgz#0b22191fd1aa6e27f7ef0820df75820bfb4ed46b"
- integrity sha512-TPMc3BW9Iso7H+9w+ytbqHK9wgOmtocyCD3PaAe5Eie50KQ/j7ThA60dGJnxItVo6yyRv5pZAYxPVob9x/fJlg==
+ web3-core "1.10.1"
+ web3-core-helpers "1.10.1"
+ web3-core-promievent "1.10.1"
+ web3-eth-abi "1.10.1"
+ web3-eth-contract "1.10.1"
+ web3-utils "1.10.1"
+
+web3-eth-iban@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz#5a46646401965b0f09a4f58e7248c8a8cd22538a"
+ integrity sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg==
dependencies:
- bn.js "4.11.8"
- web3-utils "1.2.6"
+ bn.js "^5.2.1"
+ web3-utils "1.10.0"
-web3-eth-personal@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.1.tgz#244e9911b7b482dc17c02f23a061a627c6e47faf"
- integrity sha512-RNDVSiaSoY4aIp8+Hc7z+X72H7lMb3fmAChuSBADoEc7DsJrY/d0R5qQDK9g9t2BO8oxgLrLNyBP/9ub2Hc6Bg==
+web3-eth-iban@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.1.tgz#8a40f16218cd774e965b72dc2ca36449f8fdb072"
+ integrity sha512-3n1ibzYIza9ac/iB/wEnzvnmut/u6g/x6WitxxdEMVUZshGqqnBv6HDVx25iO9TxWmala+GgmRKHnEMKCh74Yg==
dependencies:
- web3-core "1.2.1"
- web3-core-helpers "1.2.1"
- web3-core-method "1.2.1"
- web3-net "1.2.1"
- web3-utils "1.2.1"
+ bn.js "^5.2.1"
+ web3-utils "1.10.1"
-web3-eth-personal@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz#a38b3942a1d87a62070ce0622a941553c3d5aa70"
- integrity sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==
+web3-eth-personal@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.0.tgz#94d525f7a29050a0c2a12032df150ac5ea633071"
+ integrity sha512-anseKn98w/d703eWq52uNuZi7GhQeVjTC5/svrBWEKob0WZ5kPdo+EZoFN0sp5a5ubbrk/E0xSl1/M5yORMtpg==
dependencies:
"@types/node" "^12.12.6"
- web3-core "1.2.11"
- web3-core-helpers "1.2.11"
- web3-core-method "1.2.11"
- web3-net "1.2.11"
- web3-utils "1.2.11"
-
-web3-eth-personal@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.2.tgz#eee1c86a8132fa16b5e34c6d421ca92e684f0be6"
- integrity sha512-4w+GLvTlFqW3+q4xDUXvCEMU7kRZ+xm/iJC8gm1Li1nXxwwFbs+Y+KBK6ZYtoN1qqAnHR+plYpIoVo27ixI5Rg==
- dependencies:
- "@types/node" "^12.6.1"
- web3-core "1.2.2"
- web3-core-helpers "1.2.2"
- web3-core-method "1.2.2"
- web3-net "1.2.2"
- web3-utils "1.2.2"
-
-web3-eth-personal@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.6.tgz#47a0a0657ec04dd77f95451a6869d4751d324b6b"
- integrity sha512-T2NUkh1plY8d7wePXSoHnaiKOd8dLNFaQfgBl9JHU6S7IJrG9jnYD9bVxLEgRUfHs9gKf9tQpDf7AcPFdq/A8g==
- dependencies:
- "@types/node" "^12.6.1"
- web3-core "1.2.6"
- web3-core-helpers "1.2.6"
- web3-core-method "1.2.6"
- web3-net "1.2.6"
- web3-utils "1.2.6"
-
-web3-eth@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.1.tgz#b9989e2557c73a9e8ffdc107c6dafbe72c79c1b0"
- integrity sha512-/2xly4Yry5FW1i+uygPjhfvgUP/MS/Dk+PDqmzp5M88tS86A+j8BzKc23GrlA8sgGs0645cpZK/999LpEF5UdA==
- dependencies:
- underscore "1.9.1"
- web3-core "1.2.1"
- web3-core-helpers "1.2.1"
- web3-core-method "1.2.1"
- web3-core-subscriptions "1.2.1"
- web3-eth-abi "1.2.1"
- web3-eth-accounts "1.2.1"
- web3-eth-contract "1.2.1"
- web3-eth-ens "1.2.1"
- web3-eth-iban "1.2.1"
- web3-eth-personal "1.2.1"
- web3-net "1.2.1"
- web3-utils "1.2.1"
-
-web3-eth@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.11.tgz#4c81fcb6285b8caf544058fba3ae802968fdc793"
- integrity sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==
- dependencies:
- underscore "1.9.1"
- web3-core "1.2.11"
- web3-core-helpers "1.2.11"
- web3-core-method "1.2.11"
- web3-core-subscriptions "1.2.11"
- web3-eth-abi "1.2.11"
- web3-eth-accounts "1.2.11"
- web3-eth-contract "1.2.11"
- web3-eth-ens "1.2.11"
- web3-eth-iban "1.2.11"
- web3-eth-personal "1.2.11"
- web3-net "1.2.11"
- web3-utils "1.2.11"
-
-web3-eth@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.2.tgz#65a1564634a23b990efd1655bf94ad513904286c"
- integrity sha512-UXpC74mBQvZzd4b+baD4Ocp7g+BlwxhBHumy9seyE/LMIcMlePXwCKzxve9yReNpjaU16Mmyya6ZYlyiKKV8UA==
- dependencies:
- underscore "1.9.1"
- web3-core "1.2.2"
- web3-core-helpers "1.2.2"
- web3-core-method "1.2.2"
- web3-core-subscriptions "1.2.2"
- web3-eth-abi "1.2.2"
- web3-eth-accounts "1.2.2"
- web3-eth-contract "1.2.2"
- web3-eth-ens "1.2.2"
- web3-eth-iban "1.2.2"
- web3-eth-personal "1.2.2"
- web3-net "1.2.2"
- web3-utils "1.2.2"
-
-web3-eth@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.6.tgz#15a8c65fdde0727872848cae506758d302d8d046"
- integrity sha512-ROWlDPzh4QX6tlGGGlAK6X4kA2n0/cNj/4kb0nNVWkRouGmYO0R8k6s47YxYHvGiXt0s0++FUUv5vAbWovtUQw==
- dependencies:
- underscore "1.9.1"
- web3-core "1.2.6"
- web3-core-helpers "1.2.6"
- web3-core-method "1.2.6"
- web3-core-subscriptions "1.2.6"
- web3-eth-abi "1.2.6"
- web3-eth-accounts "1.2.6"
- web3-eth-contract "1.2.6"
- web3-eth-ens "1.2.6"
- web3-eth-iban "1.2.6"
- web3-eth-personal "1.2.6"
- web3-net "1.2.6"
- web3-utils "1.2.6"
-
-web3-net@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.1.tgz#edd249503315dd5ab4fa00220f6509d95bb7ab10"
- integrity sha512-Yt1Bs7WgnLESPe0rri/ZoPWzSy55ovioaP35w1KZydrNtQ5Yq4WcrAdhBzcOW7vAkIwrsLQsvA+hrOCy7mNauw==
- dependencies:
- web3-core "1.2.1"
- web3-core-method "1.2.1"
- web3-utils "1.2.1"
-
-web3-net@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.11.tgz#eda68ef25e5cdb64c96c39085cdb74669aabbe1b"
- integrity sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==
- dependencies:
- web3-core "1.2.11"
- web3-core-method "1.2.11"
- web3-utils "1.2.11"
-
-web3-net@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.2.tgz#5c3226ca72df7c591422440ce6f1203fd42ddad9"
- integrity sha512-K07j2DXq0x4UOJgae65rWZKraOznhk8v5EGSTdFqASTx7vWE/m+NqBijBYGEsQY1lSMlVaAY9UEQlcXK5HzXTw==
- dependencies:
- web3-core "1.2.2"
- web3-core-method "1.2.2"
- web3-utils "1.2.2"
-
-web3-net@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.6.tgz#035ca0fbe55282fda848ca17ebb4c8966147e5ea"
- integrity sha512-hsNHAPddrhgjWLmbESW0KxJi2GnthPcow0Sqpnf4oB6+/+ZnQHU9OsIyHb83bnC1OmunrK2vf9Ye2mLPdFIu3A==
- dependencies:
- web3-core "1.2.6"
- web3-core-method "1.2.6"
- web3-utils "1.2.6"
-
-web3-providers-http@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.1.tgz#c93ea003a42e7b894556f7e19dd3540f947f5013"
- integrity sha512-BDtVUVolT9b3CAzeGVA/np1hhn7RPUZ6YYGB/sYky+GjeO311Yoq8SRDUSezU92x8yImSC2B+SMReGhd1zL+bQ==
- dependencies:
- web3-core-helpers "1.2.1"
- xhr2-cookies "1.1.0"
-
-web3-providers-http@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.11.tgz#1cd03442c61670572d40e4dcdf1faff8bd91e7c6"
- integrity sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==
- dependencies:
- web3-core-helpers "1.2.11"
- xhr2-cookies "1.1.0"
+ web3-core "1.10.0"
+ web3-core-helpers "1.10.0"
+ web3-core-method "1.10.0"
+ web3-net "1.10.0"
+ web3-utils "1.10.0"
-web3-providers-http@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.2.tgz#155e55c1d69f4c5cc0b411ede40dea3d06720956"
- integrity sha512-BNZ7Hguy3eBszsarH5gqr9SIZNvqk9eKwqwmGH1LQS1FL3NdoOn7tgPPdddrXec4fL94CwgNk4rCU+OjjZRNDg==
+web3-eth-personal@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.1.tgz#ebeb86d4f812ef0a562129144b0ab10f0d07a0e7"
+ integrity sha512-Th4AEMbxUhH+GEqYpluWYBb+PszZ9GsdmsOhN8fo4aQHSKMfvyP+scqgOMqxK3rvobpSy/EZ6zdbAkinhoi55g==
dependencies:
- web3-core-helpers "1.2.2"
- xhr2-cookies "1.1.0"
+ "@types/node" "^12.12.6"
+ web3-core "1.10.1"
+ web3-core-helpers "1.10.1"
+ web3-core-method "1.10.1"
+ web3-net "1.10.1"
+ web3-utils "1.10.1"
-web3-providers-http@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.6.tgz#3c7b1252751fb37e53b873fce9dbb6340f5e31d9"
- integrity sha512-2+SaFCspb5f82QKuHB3nEPQOF9iSWxRf7c18fHtmnLNVkfG9SwLN1zh67bYn3tZGUdOI3gj8aX4Uhfpwx9Ezpw==
+web3-eth@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.0.tgz#38b905e2759697c9624ab080cfcf4e6c60b3a6cf"
+ integrity sha512-Z5vT6slNMLPKuwRyKGbqeGYC87OAy8bOblaqRTgg94CXcn/mmqU7iPIlG4506YdcdK3x6cfEDG7B6w+jRxypKA==
+ dependencies:
+ web3-core "1.10.0"
+ web3-core-helpers "1.10.0"
+ web3-core-method "1.10.0"
+ web3-core-subscriptions "1.10.0"
+ web3-eth-abi "1.10.0"
+ web3-eth-accounts "1.10.0"
+ web3-eth-contract "1.10.0"
+ web3-eth-ens "1.10.0"
+ web3-eth-iban "1.10.0"
+ web3-eth-personal "1.10.0"
+ web3-net "1.10.0"
+ web3-utils "1.10.0"
+
+web3-eth@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.1.tgz#6a8b46e95e0df58afc06bb052aadca89448e5af6"
+ integrity sha512-EV/d/TFVZcB54wpx2ndFnApla+aztsBOpZkbDreHcETLN1v6XmXyKozo0gYoQMZElKZ6QRRPEFvDjPeXdA7DBw==
+ dependencies:
+ web3-core "1.10.1"
+ web3-core-helpers "1.10.1"
+ web3-core-method "1.10.1"
+ web3-core-subscriptions "1.10.1"
+ web3-eth-abi "1.10.1"
+ web3-eth-accounts "1.10.1"
+ web3-eth-contract "1.10.1"
+ web3-eth-ens "1.10.1"
+ web3-eth-iban "1.10.1"
+ web3-eth-personal "1.10.1"
+ web3-net "1.10.1"
+ web3-utils "1.10.1"
+
+web3-net@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.0.tgz#be53e7f5dafd55e7c9013d49c505448b92c9c97b"
+ integrity sha512-NLH/N3IshYWASpxk4/18Ge6n60GEvWBVeM8inx2dmZJVmRI6SJIlUxbL8jySgiTn3MMZlhbdvrGo8fpUW7a1GA==
dependencies:
- web3-core-helpers "1.2.6"
- xhr2-cookies "1.1.0"
+ web3-core "1.10.0"
+ web3-core-method "1.10.0"
+ web3-utils "1.10.0"
-web3-providers-ipc@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.1.tgz#017bfc687a8fc5398df2241eb98f135e3edd672c"
- integrity sha512-oPEuOCwxVx8L4CPD0TUdnlOUZwGBSRKScCz/Ws2YHdr9Ium+whm+0NLmOZjkjQp5wovQbyBzNa6zJz1noFRvFA==
+web3-net@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.1.tgz#66c6a24c4b9b0bbd9603cc58decda346a8222365"
+ integrity sha512-06VgKyabOvj0mE7LkT1lY2A17sP32jpMAh2TniZ8ZgC3Dq36+C5LtrY17LgLSaModpvCPbpzPgbTlqB0xhssew==
dependencies:
- oboe "2.1.4"
- underscore "1.9.1"
- web3-core-helpers "1.2.1"
+ web3-core "1.10.1"
+ web3-core-method "1.10.1"
+ web3-utils "1.10.1"
-web3-providers-ipc@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz#d16d6c9be1be6e0b4f4536c4acc16b0f4f27ef21"
- integrity sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==
+web3-providers-http@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.0.tgz#864fa48675e7918c9a4374e5f664b32c09d0151b"
+ integrity sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA==
dependencies:
- oboe "2.1.4"
- underscore "1.9.1"
- web3-core-helpers "1.2.11"
+ abortcontroller-polyfill "^1.7.3"
+ cross-fetch "^3.1.4"
+ es6-promise "^4.2.8"
+ web3-core-helpers "1.10.0"
-web3-providers-ipc@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.2.tgz#c6d165a12bc68674b4cdd543ea18aec79cafc2e8"
- integrity sha512-t97w3zi5Kn/LEWGA6D9qxoO0LBOG+lK2FjlEdCwDQatffB/+vYrzZ/CLYVQSoyFZAlsDoBasVoYSWZK1n39aHA==
+web3-providers-http@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.1.tgz#cc35007edf1483b971652414c1d4d1820fbcd5c7"
+ integrity sha512-haHlG4Ig8VQdx+HdnJgJPpJwLWkAE1aXcacOfaGd2hnXPqVYRocwYqgZD/Q9pUq3u4rIZezhUaFXNRByzAfMsw==
dependencies:
- oboe "2.1.4"
- underscore "1.9.1"
- web3-core-helpers "1.2.2"
+ abortcontroller-polyfill "^1.7.3"
+ cross-fetch "^3.1.4"
+ es6-promise "^4.2.8"
+ web3-core-helpers "1.10.1"
-web3-providers-ipc@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.6.tgz#adabab5ac66b3ff8a26c7dc97af3f1a6a7609701"
- integrity sha512-b0Es+/GTZyk5FG3SgUDW+2/mBwJAXWt5LuppODptiOas8bB2khLjG6+Gm1K4uwOb+1NJGPt5mZZ8Wi7vibtQ+A==
+web3-providers-ipc@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz#9747c7a6aee96a51488e32fa7c636c3460b39889"
+ integrity sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA==
dependencies:
- oboe "2.1.4"
- underscore "1.9.1"
- web3-core-helpers "1.2.6"
+ oboe "2.1.5"
+ web3-core-helpers "1.10.0"
-web3-providers-ws@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.1.tgz#2d941eaf3d5a8caa3214eff8dc16d96252b842cb"
- integrity sha512-oqsQXzu+ejJACVHy864WwIyw+oB21nw/pI65/sD95Zi98+/HQzFfNcIFneF1NC4bVF3VNX4YHTNq2I2o97LAiA==
+web3-providers-ipc@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.1.tgz#8d1126745da4e273034bb79aae483612768cc612"
+ integrity sha512-eYrLoC2OEOlxHdsWjKpw3gwKQuQG6rcd3lc41S6cC6UpkR2pszkXUTpXVKTKFFT3eWgVAYIVz/lCeilbYLgw5A==
dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.1"
- websocket "github:web3-js/WebSocket-Node#polyfill/globalThis"
+ oboe "2.1.5"
+ web3-core-helpers "1.10.1"
-web3-providers-ws@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz#a1dfd6d9778d840561d9ec13dd453046451a96bb"
- integrity sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==
+web3-providers-ws@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz#cb0b87b94c4df965cdf486af3a8cd26daf3975e5"
+ integrity sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ==
dependencies:
eventemitter3 "4.0.4"
- underscore "1.9.1"
- web3-core-helpers "1.2.11"
- websocket "^1.0.31"
-
-web3-providers-ws@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.2.tgz#d2c05c68598cea5ad3fa6ef076c3bcb3ca300d29"
- integrity sha512-Wb1mrWTGMTXOpJkL0yGvL/WYLt8fUIXx8k/l52QB2IiKzvyd42dTWn4+j8IKXGSYYzOm7NMqv6nhA5VDk12VfA==
- dependencies:
- underscore "1.9.1"
- web3-core-helpers "1.2.2"
- websocket "github:web3-js/WebSocket-Node#polyfill/globalThis"
-
-web3-providers-ws@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.6.tgz#3cecc49f7c99f07a75076d3c54247050bc4f7e11"
- integrity sha512-20waSYX+gb5M5yKhug5FIwxBBvkKzlJH7sK6XEgdOx6BZ9YYamLmvg9wcRVtnSZO8hV/3cWenO/tRtTrHVvIgQ==
- dependencies:
- "@web3-js/websocket" "^1.0.29"
- underscore "1.9.1"
- web3-core-helpers "1.2.6"
-
-web3-shh@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.1.tgz#4460e3c1e07faf73ddec24ccd00da46f89152b0c"
- integrity sha512-/3Cl04nza5kuFn25bV3FJWa0s3Vafr5BlT933h26xovQ6HIIz61LmvNQlvX1AhFL+SNJOTcQmK1SM59vcyC8bA==
- dependencies:
- web3-core "1.2.1"
- web3-core-method "1.2.1"
- web3-core-subscriptions "1.2.1"
- web3-net "1.2.1"
+ web3-core-helpers "1.10.0"
+ websocket "^1.0.32"
-web3-shh@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.11.tgz#f5d086f9621c9a47e98d438010385b5f059fd88f"
- integrity sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==
+web3-providers-ws@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.1.tgz#b079f0a030ddc33b64a0692e7054fcfefe9fae43"
+ integrity sha512-ZCHGVH4YTVA5MCaOgmV0UJya7jTh4Vd0CFWiGqruha9/xF0fBZRYMm0awYcI9eDvVP0hRU/C9CeH5tj7UQBnTw==
dependencies:
- web3-core "1.2.11"
- web3-core-method "1.2.11"
- web3-core-subscriptions "1.2.11"
- web3-net "1.2.11"
-
-web3-shh@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.2.tgz#44ed998f2a6ba0ec5cb9d455184a0f647826a49c"
- integrity sha512-og258NPhlBn8yYrDWjoWBBb6zo1OlBgoWGT+LL5/LPqRbjPe09hlOYHgscAAr9zZGtohTOty7RrxYw6Z6oDWCg==
- dependencies:
- web3-core "1.2.2"
- web3-core-method "1.2.2"
- web3-core-subscriptions "1.2.2"
- web3-net "1.2.2"
+ eventemitter3 "4.0.4"
+ web3-core-helpers "1.10.1"
+ websocket "^1.0.32"
-web3-shh@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.6.tgz#2492616da4cac32d4c7534b890f43bac63190c14"
- integrity sha512-rouWyOOM6YMbLQd65grpj8BBezQfgNeRRX+cGyW4xsn6Xgu+B73Zvr6OtA/ftJwwa9bqHGpnLrrLMeWyy4YLUw==
+web3-shh@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.0.tgz#c2979b87e0f67a7fef2ce9ee853bd7bfbe9b79a8"
+ integrity sha512-uNUUuNsO2AjX41GJARV9zJibs11eq6HtOe6Wr0FtRUcj8SN6nHeYIzwstAvJ4fXA53gRqFMTxdntHEt9aXVjpg==
dependencies:
- web3-core "1.2.6"
- web3-core-method "1.2.6"
- web3-core-subscriptions "1.2.6"
- web3-net "1.2.6"
+ web3-core "1.10.0"
+ web3-core-method "1.10.0"
+ web3-core-subscriptions "1.10.0"
+ web3-net "1.10.0"
-web3-utils@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.1.tgz#21466e38291551de0ab34558de21512ac4274534"
- integrity sha512-Mrcn3l58L+yCKz3zBryM6JZpNruWuT0OCbag8w+reeNROSGVlXzUQkU+gtAwc9JCZ7tKUyg67+2YUGqUjVcyBA==
+web3-shh@1.10.1:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.1.tgz#ded94bf40bef752f52f0380f62386dd5ea00f0af"
+ integrity sha512-PoRfyM5NtHiQufxWDEgLhxpeDkkZos/ijjiT1IQafmD0iurMBxLU+k9OjRX2oblVyP3nPl1sSBQTYFe3b33JGA==
dependencies:
- bn.js "4.11.8"
- eth-lib "0.2.7"
- ethjs-unit "0.1.6"
- number-to-bn "1.7.0"
- randomhex "0.1.5"
- underscore "1.9.1"
- utf8 "3.0.0"
+ web3-core "1.10.1"
+ web3-core-method "1.10.1"
+ web3-core-subscriptions "1.10.1"
+ web3-net "1.10.1"
-web3-utils@1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.11.tgz#af1942aead3fb166ae851a985bed8ef2c2d95a82"
- integrity sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==
+web3-utils@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578"
+ integrity sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==
dependencies:
- bn.js "^4.11.9"
- eth-lib "0.2.8"
+ 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"
- underscore "1.9.1"
utf8 "3.0.0"
-web3-utils@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.2.tgz#b53a08c40d2c3f31d3c4a28e7d749405df99c8c0"
- integrity sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==
+web3-utils@1.10.1, web3-utils@^1.0.0-beta.31, web3-utils@^1.3.6:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.1.tgz#97532130d85358628bc0ff14d94b7e9449786983"
+ integrity sha512-r6iUUw/uMnNcWXjhRv33Nyrhxq3VGOPBXeSzxhOXIci4SvC/LPTpROY0uTrMX7ztKyODYrHp8WhTkEf+ZnHssw==
dependencies:
- bn.js "4.11.8"
- eth-lib "0.2.7"
+ "@ethereumjs/util" "^8.1.0"
+ bn.js "^5.2.1"
ethereum-bloom-filters "^1.0.6"
+ ethereum-cryptography "^2.1.2"
ethjs-unit "0.1.6"
number-to-bn "1.7.0"
randombytes "^2.1.0"
- underscore "1.9.1"
utf8 "3.0.0"
-web3-utils@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.6.tgz#b9a25432da00976457fcc1094c4af8ac6d486db9"
- integrity sha512-8/HnqG/l7dGmKMgEL9JeKPTtjScxOePTzopv5aaKFExPfaBrYRkgoMqhoowCiAl/s16QaTn4DoIF1QC4YsT7Mg==
- dependencies:
- bn.js "4.11.8"
- eth-lib "0.2.7"
- ethereum-bloom-filters "^1.0.6"
- ethjs-unit "0.1.6"
- number-to-bn "1.7.0"
- randombytes "^2.1.0"
- underscore "1.9.1"
- utf8 "3.0.0"
+web3@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.0.tgz#2fde0009f59aa756c93e07ea2a7f3ab971091274"
+ integrity sha512-YfKY9wSkGcM8seO+daR89oVTcbu18NsVfvOngzqMYGUU0pPSQmE57qQDvQzUeoIOHAnXEBNzrhjQJmm8ER0rng==
+ dependencies:
+ web3-bzz "1.10.0"
+ web3-core "1.10.0"
+ web3-eth "1.10.0"
+ web3-eth-personal "1.10.0"
+ web3-net "1.10.0"
+ web3-shh "1.10.0"
+ web3-utils "1.10.0"
+
+web3@1.10.1, web3@^1.0.0-beta.34:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.1.tgz#6435783cb2c0a8347f62b7b1a6ade431f19dce2a"
+ integrity sha512-Ry+teufg6GYwIlLijyVTzZmnP+pu55vBU6P7rwK/rZidsMhc3m1lA5UXxiUVzBYZ8dvzV6+dVvOh68RrwrsI1w==
+ dependencies:
+ web3-bzz "1.10.1"
+ web3-core "1.10.1"
+ web3-eth "1.10.1"
+ web3-eth-personal "1.10.1"
+ web3-net "1.10.1"
+ web3-shh "1.10.1"
+ web3-utils "1.10.1"
+
+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==
-web3@1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.1.tgz#5d8158bcca47838ab8c2b784a2dee4c3ceb4179b"
- integrity sha512-nNMzeCK0agb5i/oTWNdQ1aGtwYfXzHottFP2Dz0oGIzavPMGSKyVlr8ibVb1yK5sJBjrWVnTdGaOC2zKDFuFRw==
- dependencies:
- web3-bzz "1.2.1"
- web3-core "1.2.1"
- web3-eth "1.2.1"
- web3-eth-personal "1.2.1"
- web3-net "1.2.1"
- web3-shh "1.2.1"
- web3-utils "1.2.1"
-
-web3@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.2.tgz#b1b8b69aafdf94cbaeadbb68a8aa1df2ef266aec"
- integrity sha512-/ChbmB6qZpfGx6eNpczt5YSUBHEA5V2+iUCbn85EVb3Zv6FVxrOo5Tv7Lw0gE2tW7EEjASbCyp3mZeiZaCCngg==
- dependencies:
- "@types/node" "^12.6.1"
- web3-bzz "1.2.2"
- web3-core "1.2.2"
- web3-eth "1.2.2"
- web3-eth-personal "1.2.2"
- web3-net "1.2.2"
- web3-shh "1.2.2"
- web3-utils "1.2.2"
-
-web3@1.2.6:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.6.tgz#c497dcb14cdd8d6d9fb6b445b3b68ff83f8ccf68"
- integrity sha512-tpu9fLIComgxGrFsD8LUtA4s4aCZk7px8UfcdEy6kS2uDi/ZfR07KJqpXZMij7Jvlq+cQrTAhsPSiBVvoMaivA==
- dependencies:
- "@types/node" "^12.6.1"
- web3-bzz "1.2.6"
- web3-core "1.2.6"
- web3-eth "1.2.6"
- web3-eth-personal "1.2.6"
- web3-net "1.2.6"
- web3-shh "1.2.6"
- web3-utils "1.2.6"
-
-web3@^1.2.11:
- version "1.2.11"
- resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975"
- integrity sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==
- dependencies:
- web3-bzz "1.2.11"
- web3-core "1.2.11"
- web3-eth "1.2.11"
- web3-eth-personal "1.2.11"
- web3-net "1.2.11"
- web3-shh "1.2.11"
- web3-utils "1.2.11"
-
-websocket@^1.0.31:
- version "1.0.31"
- resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.31.tgz#e5d0f16c3340ed87670e489ecae6144c79358730"
- integrity sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==
+websocket@^1.0.32:
+ version "1.0.34"
+ resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111"
+ integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==
dependencies:
+ bufferutil "^4.0.1"
debug "^2.2.0"
es5-ext "^0.10.50"
- nan "^2.14.0"
typedarray-to-buffer "^3.1.5"
+ utf-8-validate "^5.0.2"
yaeti "^0.0.6"
-"websocket@github:web3-js/WebSocket-Node#polyfill/globalThis":
- version "1.0.29"
- resolved "https://codeload.github.com/web3-js/WebSocket-Node/tar.gz/ef5ea2f41daf4a2113b80c9223df884b4d56c400"
+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:
- debug "^2.2.0"
- es5-ext "^0.10.50"
- nan "^2.14.0"
- typedarray-to-buffer "^3.1.5"
- yaeti "^0.0.6"
+ tr46 "~0.0.3"
+ webidl-conversions "^3.0.0"
-whatwg-fetch@2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
- integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==
+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-module@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
+ integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==
which-module@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
- integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
+ 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.10, which-typed-array@^1.1.2:
+ version "1.1.10"
+ resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.10.tgz#74baa2789991905c2076abb317103b866c64e69e"
+ integrity sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA==
+ 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.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:
+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"
-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"
-
wide-align@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
@@ -8064,20 +8810,41 @@ wide-align@1.1.3:
dependencies:
string-width "^1.0.2 || 2"
-word-wrap@^1.2.3, word-wrap@~1.2.3:
+window-size@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
+ integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==
+
+word-wrap@~1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
-wordwrap@^1.0.0:
+wordwrap@>=0.0.2, wordwrap@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
- integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
+ integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
-workerpool@6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.0.0.tgz#85aad67fa1a2c8ef9386a1b43539900f61d03d58"
- integrity sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==
+wordwrapjs@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f"
+ integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==
+ dependencies:
+ reduce-flatten "^2.0.0"
+ typical "^5.2.0"
+
+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@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+ integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
wrap-ansi@^5.1.0:
version "5.1.0"
@@ -8088,17 +8855,29 @@ wrap-ansi@^5.1.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"
+ 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 sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+ integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
-write@1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"
- integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==
- dependencies:
- mkdirp "^0.5.1"
+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@8.5.0:
+ version "8.5.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
+ integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
ws@^3.0.0:
version "3.3.3"
@@ -8109,12 +8888,10 @@ ws@^3.0.0:
safe-buffer "~5.1.0"
ultron "~1.1.0"
-ws@^5.1.1:
- version "5.2.2"
- resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f"
- integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==
- dependencies:
- async-limiter "~1.0.0"
+ws@^7.4.6:
+ version "7.5.9"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
+ integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
xhr-request-promise@^0.1.2:
version "0.1.3"
@@ -8136,51 +8913,52 @@ xhr-request@^1.0.1, xhr-request@^1.1.0:
url-set-query "^1.0.0"
xhr "^2.0.4"
-xhr2-cookies@1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48"
- integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=
- dependencies:
- cookiejar "^2.1.1"
-
-xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd"
- integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==
+xhr@^2.0.4, xhr@^2.3.3:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d"
+ integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==
dependencies:
- global "~4.3.0"
+ global "~4.4.0"
is-function "^1.0.1"
parse-headers "^2.0.0"
xtend "^4.0.0"
+xml@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
+ integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==
+
xmlhttprequest@1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
- integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=
+ integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==
-xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1:
+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==
-xtend@~2.1.1:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b"
- integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os=
- dependencies:
- object-keys "~0.4.0"
+y18n@^3.2.1:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
+ integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==
y18n@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
- integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
+ 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"
+ integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yaeti@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577"
- integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=
+ integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==
-yallist@^3.0.0, yallist@^3.0.3:
+yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
@@ -8190,7 +8968,7 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-yargs-parser@13.1.2, yargs-parser@^13.1.0, yargs-parser@^13.1.2:
+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==
@@ -8198,6 +8976,24 @@ yargs-parser@13.1.2, yargs-parser@^13.1.0, yargs-parser@^13.1.2:
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"
+ integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
+
+yargs-parser@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4"
+ integrity sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==
+ dependencies:
+ camelcase "^3.0.0"
+ lodash.assign "^4.0.6"
+
+yargs-parser@^20.2.2, yargs-parser@^20.2.3:
+ 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@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f"
@@ -8207,22 +9003,15 @@ yargs-unparser@1.6.0:
lodash "^4.17.15"
yargs "^13.3.0"
-yargs@13.2.4:
- version "13.2.4"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83"
- integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==
+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:
- cliui "^5.0.0"
- find-up "^3.0.0"
- get-caller-file "^2.0.1"
- os-locale "^3.1.0"
- 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.0"
+ camelcase "^6.0.0"
+ decamelize "^4.0.0"
+ flat "^5.0.2"
+ is-plain-obj "^2.1.0"
yargs@13.3.2, yargs@^13.3.0:
version "13.3.2"
@@ -8240,15 +9029,45 @@ yargs@13.3.2, yargs@^13.3.0:
y18n "^4.0.0"
yargs-parser "^13.1.2"
-yauzl@^2.4.2:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
- integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
+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:
- buffer-crc32 "~0.2.3"
- fd-slicer "~1.1.0"
+ cliui "^7.0.2"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.0"
+ y18n "^5.0.5"
+ yargs-parser "^20.2.2"
+
+yargs@^4.7.1:
+ version "4.8.1"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0"
+ integrity sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==
+ dependencies:
+ cliui "^3.2.0"
+ decamelize "^1.1.1"
+ get-caller-file "^1.0.1"
+ lodash.assign "^4.0.3"
+ os-locale "^1.4.0"
+ read-pkg-up "^1.0.1"
+ require-directory "^2.1.1"
+ require-main-filename "^1.0.1"
+ set-blocking "^2.0.0"
+ string-width "^1.0.1"
+ which-module "^1.0.0"
+ window-size "^0.2.0"
+ y18n "^3.2.1"
+ yargs-parser "^2.4.1"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
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==